fanout works on many items at once, a bounded number at a time, and
reports them as progress asks.
- Map announces a target for each item, queued, before the first runs.
- Four run at once: the Limit.
- A place comes free; the next item takes it. exe03 fails.
- The step ends. Its error names the items that failed.
The step ends. Its error names the items that failed.
capture := &progresstest.Capture{}
bus := progress.NewBus(progress.BusOptions{Sinks: []progress.Sink{capture}})
ctx := progress.WithBus(context.Background(), bus)
nodes := []string{"exe01", "exe02", "exe03", "exe04"}
outcomes, err := fanout.Map(ctx, nodes, fanout.MapOptions[string]{Step: "uptime", Limit: 2},
func(_ context.Context, node string) (string, error) {
if node == "exe03" {
return "", fmt.Errorf("%s: no answer", node)
}
return strings.ToUpper(node), nil
})
for i, o := range outcomes {
fmt.Println(nodes[i], o.Value, o.Err)
}
fmt.Println(err)
bus.Close()
fmt.Print(capture.Tree())exe01 EXE01 <nil>
exe02 EXE02 <nil>
exe03 exe03: no answer
exe04 EXE04 <nil>
1 of 4 failed: exe03
step uptime total=4 limit=2 [fold]: failed (target): 1 of 4 failed: exe03
target exe03: failed (target): {}: no answer
target exe[01-02,04]: okfanout/example_test.go. CI runs it and checks its output.The main names#
| Name | What it does |
|---|---|
fanout.Map, fanout.MapOptions | a step with a target for each item; the outcomes in the order of the items |
fanout.Each | the bounded loop alone, which reports nothing and recovers nothing |
fanout.Batches | a node set in batches, one after the other, with a pause between |
fanout.Keyed | at most a limit under way on each key, such as a gateway |
fanout.FailureError, fanout.Summary | the default error of a step, and what it sums up |
fanout.PanicError, fanout.Recovered | a panic in the work of an item, as its error |
A limit below one is fanout.DefaultLimit, 16, for Each and
Map, and one for Keyed.
CAUTION
Only Map recovers a panic. A panic in the work of Each ends the
process, as in any goroutine, unless the work recovers it.