-
Notifications
You must be signed in to change notification settings - Fork 436
/
startable.ts
114 lines (98 loc) · 2.5 KB
/
startable.ts
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
/**
* Implemented by components that have a lifecycle
*/
export interface Startable {
/**
* If implemented, this method will be invoked before the start method.
*
* It should not assume any other components have been started.
*/
beforeStart?(): void | Promise<void>
/**
* This method will be invoked to start the component.
*
* It should not assume that any other components have been started.
*/
start(): void | Promise<void>
/**
* If implemented, this method will be invoked after the start method.
*
* All other components will have had their start method invoked before this method is called.
*/
afterStart?(): void | Promise<void>
/**
* If implemented, this method will be invoked before the stop method.
*
* Any other components will still be running when this method is called.
*/
beforeStop?(): void | Promise<void>
/**
* This method will be invoked to stop the component.
*
* It should not assume any other components are running when it is called.
*/
stop(): void | Promise<void>
/**
* If implemented, this method will be invoked after the stop method.
*
* All other components will have had their stop method invoked before this method is called.
*/
afterStop?(): void | Promise<void>
}
export function isStartable (obj: any): obj is Startable {
return obj != null && typeof obj.start === 'function' && typeof obj.stop === 'function'
}
export async function start (...objs: any[]): Promise<void> {
const startables: Startable[] = []
for (const obj of objs) {
if (isStartable(obj)) {
startables.push(obj)
}
}
await Promise.all(
startables.map(async s => {
if (s.beforeStart != null) {
await s.beforeStart()
}
})
)
await Promise.all(
startables.map(async s => {
await s.start()
})
)
await Promise.all(
startables.map(async s => {
if (s.afterStart != null) {
await s.afterStart()
}
})
)
}
export async function stop (...objs: any[]): Promise<void> {
const startables: Startable[] = []
for (const obj of objs) {
if (isStartable(obj)) {
startables.push(obj)
}
}
await Promise.all(
startables.map(async s => {
if (s.beforeStop != null) {
await s.beforeStop()
}
})
)
await Promise.all(
startables.map(async s => {
await s.stop()
})
)
await Promise.all(
startables.map(async s => {
if (s.afterStop != null) {
await s.afterStop()
}
})
)
}