refactor(collect): make verbose mode emit progress
Verbose is now a real AX-facing behaviour instead of dead documentation. Excavator emits additional progress telemetry when verbose mode is enabled, and the new regression test protects that path. Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
9a0a1f4435
commit
1bccde8828
3 changed files with 42 additions and 0 deletions
|
|
@ -9,8 +9,10 @@ package collect
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
filepath "dappco.re/go/core/scm/internal/ax/filepathx"
|
filepath "dappco.re/go/core/scm/internal/ax/filepathx"
|
||||||
|
fmt "dappco.re/go/core/scm/internal/ax/fmtx"
|
||||||
|
|
||||||
"dappco.re/go/core/io"
|
"dappco.re/go/core/io"
|
||||||
|
core "dappco.re/go/core/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Collector is the interface all collection sources implement.
|
// Collector is the interface all collection sources implement.
|
||||||
|
|
@ -91,6 +93,19 @@ func NewConfigWithMedium(m io.Medium, outputDir string) *Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// verboseProgress emits a progress event when verbose mode is enabled.
|
||||||
|
// Usage: verboseProgress(cfg, "excavator", "loading state")
|
||||||
|
func verboseProgress(cfg *Config, source, message string) {
|
||||||
|
if cfg == nil || !cfg.Verbose {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if cfg.Dispatcher != nil {
|
||||||
|
cfg.Dispatcher.EmitProgress(source, message, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
core.Warn(fmt.Sprintf("%s: %s", source, message))
|
||||||
|
}
|
||||||
|
|
||||||
// MergeResults combines multiple results into a single aggregated result.
|
// MergeResults combines multiple results into a single aggregated result.
|
||||||
// Usage: MergeResults(...)
|
// Usage: MergeResults(...)
|
||||||
func MergeResults(source string, results ...*Result) *Result {
|
func MergeResults(source string, results ...*Result) *Result {
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,11 @@ func (e *Excavator) Run(ctx context.Context, cfg *Config) (*Result, error) {
|
||||||
if cfg.Dispatcher != nil {
|
if cfg.Dispatcher != nil {
|
||||||
cfg.Dispatcher.EmitStart(e.Name(), fmt.Sprintf("Starting excavation with %d collectors", len(e.Collectors)))
|
cfg.Dispatcher.EmitStart(e.Name(), fmt.Sprintf("Starting excavation with %d collectors", len(e.Collectors)))
|
||||||
}
|
}
|
||||||
|
verboseProgress(cfg, e.Name(), fmt.Sprintf("queueing %d collectors", len(e.Collectors)))
|
||||||
|
|
||||||
// Load state if resuming
|
// Load state if resuming
|
||||||
if e.Resume && cfg.State != nil {
|
if e.Resume && cfg.State != nil {
|
||||||
|
verboseProgress(cfg, e.Name(), "loading resume state")
|
||||||
if err := cfg.State.Load(); err != nil {
|
if err := cfg.State.Load(); err != nil {
|
||||||
return result, core.E("collect.Excavator.Run", "failed to load state", err)
|
return result, core.E("collect.Excavator.Run", "failed to load state", err)
|
||||||
}
|
}
|
||||||
|
|
@ -57,6 +59,7 @@ func (e *Excavator) Run(ctx context.Context, cfg *Config) (*Result, error) {
|
||||||
if cfg.Dispatcher != nil {
|
if cfg.Dispatcher != nil {
|
||||||
cfg.Dispatcher.EmitProgress(e.Name(), fmt.Sprintf("[scan] Would run collector: %s", c.Name()), nil)
|
cfg.Dispatcher.EmitProgress(e.Name(), fmt.Sprintf("[scan] Would run collector: %s", c.Name()), nil)
|
||||||
}
|
}
|
||||||
|
verboseProgress(cfg, e.Name(), fmt.Sprintf("scan-only collector: %s", c.Name()))
|
||||||
}
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
@ -70,6 +73,7 @@ func (e *Excavator) Run(ctx context.Context, cfg *Config) (*Result, error) {
|
||||||
cfg.Dispatcher.EmitProgress(e.Name(),
|
cfg.Dispatcher.EmitProgress(e.Name(),
|
||||||
fmt.Sprintf("Running collector %d/%d: %s", i+1, len(e.Collectors), c.Name()), nil)
|
fmt.Sprintf("Running collector %d/%d: %s", i+1, len(e.Collectors), c.Name()), nil)
|
||||||
}
|
}
|
||||||
|
verboseProgress(cfg, e.Name(), fmt.Sprintf("dispatching collector %d/%d: %s", i+1, len(e.Collectors), c.Name()))
|
||||||
|
|
||||||
// Check if we should skip (already completed in a previous run)
|
// Check if we should skip (already completed in a previous run)
|
||||||
if e.Resume && cfg.State != nil {
|
if e.Resume && cfg.State != nil {
|
||||||
|
|
@ -80,6 +84,7 @@ func (e *Excavator) Run(ctx context.Context, cfg *Config) (*Result, error) {
|
||||||
fmt.Sprintf("Skipping %s (already collected %d items on %s)",
|
fmt.Sprintf("Skipping %s (already collected %d items on %s)",
|
||||||
c.Name(), entry.Items, entry.LastRun.Format(time.RFC3339)), nil)
|
c.Name(), entry.Items, entry.LastRun.Format(time.RFC3339)), nil)
|
||||||
}
|
}
|
||||||
|
verboseProgress(cfg, e.Name(), fmt.Sprintf("resume skip: %s", c.Name()))
|
||||||
result.Skipped++
|
result.Skipped++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -115,6 +120,7 @@ func (e *Excavator) Run(ctx context.Context, cfg *Config) (*Result, error) {
|
||||||
|
|
||||||
// Save state
|
// Save state
|
||||||
if cfg.State != nil {
|
if cfg.State != nil {
|
||||||
|
verboseProgress(cfg, e.Name(), "saving resume state")
|
||||||
if err := cfg.State.Save(); err != nil {
|
if err := cfg.State.Save(); err != nil {
|
||||||
if cfg.Dispatcher != nil {
|
if cfg.Dispatcher != nil {
|
||||||
cfg.Dispatcher.EmitError(e.Name(), fmt.Sprintf("Failed to save state: %v", err), nil)
|
cfg.Dispatcher.EmitError(e.Name(), fmt.Sprintf("Failed to save state: %v", err), nil)
|
||||||
|
|
|
||||||
|
|
@ -203,3 +203,24 @@ func TestExcavator_Run_Good_Events_Good(t *testing.T) {
|
||||||
assert.Equal(t, 1, startCount)
|
assert.Equal(t, 1, startCount)
|
||||||
assert.Equal(t, 1, completeCount)
|
assert.Equal(t, 1, completeCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestExcavator_Run_Good_VerboseProgress_Good(t *testing.T) {
|
||||||
|
m := io.NewMockMedium()
|
||||||
|
cfg := NewConfigWithMedium(m, "/output")
|
||||||
|
cfg.Limiter = nil
|
||||||
|
cfg.Verbose = true
|
||||||
|
|
||||||
|
var progressCount int
|
||||||
|
cfg.Dispatcher.On(EventProgress, func(e Event) {
|
||||||
|
progressCount++
|
||||||
|
})
|
||||||
|
|
||||||
|
c1 := &mockCollector{name: "source-a", items: 1}
|
||||||
|
e := &Excavator{
|
||||||
|
Collectors: []Collector{c1},
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := e.Run(context.Background(), cfg)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.GreaterOrEqual(t, progressCount, 2)
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue