5
5
"time"
6
6
)
7
7
8
+ var DefaultComponentShutdownTimeout = 30 * time .Second
9
+
8
10
type C interface {
9
11
Add (runner Runnable )
10
12
AddService (service Runnable )
@@ -15,59 +17,71 @@ type component struct {
15
17
services * group
16
18
}
17
19
20
+ // Component manages two groups of Runnable, processes and services.
21
+ // Services are stopped after processes.
22
+ // The intended purposes is to manage the simplest form of runnable dependencies.
18
23
func Component (processes ... Runnable ) * component {
19
24
return & component {
20
- processes : & group {timeout : 30 * time . Second , runnables : processes },
21
- services : & group {timeout : 30 * time . Second },
25
+ processes : & group {timeout : DefaultComponentShutdownTimeout , runnables : processes },
26
+ services : & group {timeout : DefaultComponentShutdownTimeout },
22
27
}
23
28
}
24
29
25
- // WithShutdownTimeout changes the default timeout (30s).
26
- func (c * component ) WithShutdownTimeout (process , service time.Duration ) * component {
27
- c .processes .timeout = process
28
- c .services .timeout = service
30
+ // WithProcessShutdownTimeout changes the shutdown timeout of the process runnables.
31
+ // See also DefaultComponentShutdownTimeout.
32
+ func (c * component ) WithProcessShutdownTimeout (timeout time.Duration ) * component {
33
+ c .processes .timeout = timeout
34
+ return c
35
+ }
36
+
37
+ // WithServiceShutdownTimeout changes the shutdown timeout of the service runnables.
38
+ // See also DefaultComponentShutdownTimeout.
39
+ func (c * component ) WithServiceShutdownTimeout (timeout time.Duration ) * component {
40
+ c .services .timeout = timeout
29
41
return c
30
42
}
31
43
32
- // Add registers runnables as process. Processes will be shutdown before services.
33
- func (c * component ) Add (runner ... Runnable ) {
34
- c .processes .runnables = append (c .processes .runnables , runner ... )
44
+ // AddProcess registers runnables as process. Processes will be shutdown before services.
45
+ func (c * component ) AddProcess (runner ... Runnable ) * component {
46
+ c .processes .Add (runner ... )
47
+ return c
35
48
}
36
49
37
50
// Add registers runnables as services. Services will be shutdown after processes.
38
- func (c * component ) AddService (service ... Runnable ) {
39
- c .services .runnables = append (c .services .runnables , service ... )
51
+ func (c * component ) AddService (service ... Runnable ) * component {
52
+ c .services .Add (service ... )
53
+ return c
40
54
}
41
55
42
56
func (c * component ) Run (ctx context.Context ) error {
43
- ctxValues := ContextValues (ctx )
57
+ ctxNoCancel := context . WithoutCancel (ctx )
44
58
45
59
// Starting
46
60
47
61
Log (c , "starting services" )
48
- c .services .start ( ctxValues )
62
+ c .services .Start ( ctxNoCancel )
49
63
50
64
Log (c , "starting processes" )
51
- c .processes .start ( ctxValues )
65
+ c .processes .Start ( ctxNoCancel )
52
66
53
67
// Waiting for shutdown
54
68
55
69
select {
56
- case <- c .processes .errors :
57
- Log (c , "a runner stopped" )
58
- case <- c .services .errors :
59
- Log (c , "a service stopped" )
70
+ case r := <- c .processes .StoppedRunnables () :
71
+ Log (c , "process stopped: %s" , findName ( r ) )
72
+ case r := <- c .services .StoppedRunnables () :
73
+ Log (c , "service stopped: %s" , findName ( r ) )
60
74
case <- ctx .Done ():
61
75
Log (c , "context cancelled" )
62
76
}
63
77
64
78
// shutdown
65
79
66
80
Log (c , "shutting down processes" )
67
- c .processes .stop ()
81
+ c .processes .Stop ()
68
82
69
83
Log (c , "shutting down services" )
70
- c .services .stop ()
84
+ c .services .Stop ()
71
85
72
86
Log (c , "shutdown complete" )
73
87
return ctx .Err ()
0 commit comments