forked from bassjacob/asclepius
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
85 lines (74 loc) · 2.02 KB
/
index.js
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
// @flow
/* ::
type resultType = { healthy: bool, name: string, reason: string };
type healthcheckType = () => Promise<resultType>;
type resultsType = { [string]: { healthy: bool, reason: string } };
*/
function timeout(timeoutDelay /* : number */) /* : Promise<void> */ {
return new Promise(resolve => {
setTimeout(() => resolve(), timeoutDelay);
});
}
const reduceResults = results =>
results.reduce(
(p, c) =>
Object.assign(p, { [c.name]: { healthy: c.healthy, reason: c.reason } }),
{}
);
const mapInvoke = fs => fs.map(f => f());
function format(results /* : resultsType */) {
return {
healthy: !Object.keys(results).some(
key => results[key] && results[key].healthy === false
),
results,
};
}
function makeRunner(
healthchecks /* : Array<healthcheckType> */
) /* : () => Promise<{ healthy: bool, results: resultsType }> */ {
return () =>
Promise.all(mapInvoke(healthchecks))
.then(reduceResults)
.then(format);
}
function healthcheck(
name /* : string */,
check /* : void => Promise<mixed> */,
timeoutDelay /* : ?number */
) /* : healthcheckType */ {
const t = timeoutDelay;
const run =
typeof t === 'number'
? () =>
Promise.race([
check(),
timeout(t).then(() => Promise.reject(`timed out after ${t}ms`)),
])
: check;
return () =>
run().then(
() => ({ healthy: true, name, reason: 'OK' }),
(reason /* : string */) => ({ healthy: false, name, reason })
);
}
/* :: type resType = { status: number => resType, json: mixed => void } */
function makeRoute(healthchecks /* : Array<healthcheckType> */) {
const runner = makeRunner(healthchecks);
return (req /* : mixed */, res /* : resType */, next /* : * => void */) =>
runner()
.then(
results =>
results.healthy
? res.status(200).json(results)
: res.status(500).json(results)
)
.catch(next);
}
module.exports = {
healthcheck,
timeout,
makeRunner,
format,
makeRoute,
};