-
Notifications
You must be signed in to change notification settings - Fork 14
/
worker.go
52 lines (47 loc) · 1.48 KB
/
worker.go
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
// Copyright 2012-2016 Canonical Ltd.
// Licensed under the LGPLv3, see LICENCE file for details.
package worker
// Worker describes any type whose validity and/or activity is bounded
// in time. Most frequently, they will represent the duration of some
// task or tasks running on internal goroutines, but it's possible and
// rational to use them to represent any resource that might become
// invalid.
//
// Worker implementations must be goroutine-safe.
type Worker interface {
// Kill asks the worker to stop and returns immediately.
Kill()
// Wait waits for the worker to complete and returns any
// error encountered when it was running or stopping.
Wait() error
}
// Stop kills the given Worker and waits for it to complete.
func Stop(worker Worker) error {
worker.Kill()
return worker.Wait()
}
// Dead returns a channel that will be closed when the supplied
// Worker has completed. If the worker implements
// interface {Dead() <-chan struct{}}
// then if the result of that method is non-nil, it will be
// returned.
//
// Don't be too casual about calling Dead -- for example, in a
// standard select loop, `case <-worker.Dead(w):` will create
// one new goroutine per iteration, which is... untidy.
func Dead(worker Worker) <-chan struct{} {
type deader interface {
Dead() <-chan struct{}
}
if worker, ok := worker.(deader); ok {
if ch := worker.Dead(); ch != nil {
return ch
}
}
dead := make(chan struct{})
go func() {
defer close(dead)
worker.Wait()
}()
return dead
}