Repository navigation
Expand file tree
/
Copy pathexample_test.go
More file actions
137 lines (108 loc) · 2.71 KB
/
Copy pathexample_test.go
File metadata and controls
137 lines (108 loc) · 2.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package taskgroup_test
import (
"context"
"errors"
"fmt"
"github.com/gokern/taskgroup"
)
// A zero-configuration group that runs one task to completion.
func ExampleTaskGroup() {
tg := taskgroup.New()
tg.AddFunc(func(context.Context) error {
fmt.Println("working")
return nil
})
err := tg.Run(context.Background())
if err != nil {
fmt.Println("error:", err)
}
// Output:
// working
}
// A task with an explicit shutdown function. Interrupt runs when the group
// starts shutting down.
func ExampleNewTask() {
task := taskgroup.NewTask(func(ctx context.Context) error {
<-ctx.Done()
return ctx.Err()
}).Interrupt(func(error) {
fmt.Println("stop")
})
tg := taskgroup.New()
tg.Add(task)
// Second task returns immediately, triggering shutdown of the first.
tg.AddFunc(func(context.Context) error {
fmt.Println("done")
return nil
})
_ = tg.Run(context.Background())
// Output:
// done
// stop
}
// Deferred cleanup runs after all tasks have returned, in LIFO order.
func ExampleTaskGroup_Defer() {
tg := taskgroup.New()
tg.Defer(func(error) error {
fmt.Println("close db")
return nil
})
tg.Defer(func(error) error {
fmt.Println("flush metrics")
return nil
})
tg.AddFunc(func(context.Context) error {
fmt.Println("work")
return nil
})
_ = tg.Run(context.Background())
// Output:
// work
// flush metrics
// close db
}
// SignalTask stops the group on shutdown signals. Detect the cause with
// IsSignalError and SignalFromError.
func ExampleSignalTask() {
tg := taskgroup.New()
tg.Add(taskgroup.SignalTask())
// Immediately canceled context so the example terminates deterministically.
ctx, cancel := context.WithCancel(context.Background())
cancel()
err := tg.Run(ctx)
switch {
case taskgroup.IsSignalError(err):
sig, _ := taskgroup.SignalFromError(err)
fmt.Println("stopped by signal:", sig)
case err != nil:
fmt.Println("failed:", err)
default:
// A canceled run context is not an error: the caller asked for the
// stop, so the group has nothing to report.
fmt.Println("stopped cleanly")
}
// Output:
// stopped cleanly
}
// Run drops what a task reports once the group is stopping. A task whose error
// should be heard anyway reports it itself.
func ExampleTaskGroup_Run_droppedError() {
stop := make(chan struct{})
tg := taskgroup.New()
tg.Add(taskgroup.NewTask(func(context.Context) error {
<-stop
err := errors.New("flush failed")
fmt.Println("worker:", err)
return err
}).Interrupt(func(error) {
close(stop)
}))
// A one-shot job that finishes first and ends the run.
tg.AddFunc(func(context.Context) error {
return nil
})
fmt.Println("Run:", tg.Run(context.Background()))
// Output:
// worker: flush failed
// Run: <nil>
}