-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathrun.go
66 lines (53 loc) · 1.83 KB
/
run.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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package process
import (
"context"
"sync"
)
// State tracks the current state of application execution.
type State struct {
stateLock sync.RWMutex
machine *machine
shutdownOnce sync.Once
errors <-chan error
errorsSeen []error
}
// Run builds a machine to invoke the processes registered to the given container. This
// method returns a state value that can be used to signal the application to begin shutdown,
// and to block until the active processes have exited.
func Run(ctx context.Context, container *Container, configs ...MachineConfigFunc) *State {
machineBuilder := newMachineBuilder(configs...)
runFunc := machineBuilder.buildRun(container)
shutdownFunc := machineBuilder.buildShutdown(container)
errors := make(chan error)
machine := newMachine(runFunc, shutdownFunc, errors)
machine.run(ctx)
return &State{machine: machine, errors: errors}
}
// Wait blocks until all processes exit cleanly or until an error occurs during execution
// of the machine built via Run. If an error occurs, all other running processes are
// signalled to exit. This method unblocks once all processes have exited. This method
// returns a boolean flag indicating a clean exit.
func (s *State) Wait(ctx context.Context) bool {
ok := true
for err := range s.errors {
ok = false
s.Shutdown(ctx)
s.stateLock.Lock()
s.errorsSeen = append(s.errorsSeen, err)
s.stateLock.Unlock()
}
return ok
}
// Errors returns a slice of errors encountered while running the processes. The Errors method can
// be used once the Wait method returns to find the errors returned by the processes.
func (s *State) Errors() []error {
s.stateLock.RLock()
defer s.stateLock.RUnlock()
return s.errorsSeen
}
// Shutdown signals all running processes to exit.
func (s *State) Shutdown(ctx context.Context) {
s.shutdownOnce.Do(func() {
s.machine.shutdown(ctx)
})
}