UNPKG

1.83 kBJavaScriptView Raw
1const assert = require('assert')
2const events = require('events')
3const Isochronous = require('isochronous')
4const isRunning = require('is-running')
5
6class Killer extends events.EventEmitter {
7 constructor (interval, printer = { say: () => {} }) {
8 super()
9 this._isochronous = new Isochronous(interval, true, async () => {
10 let i = 0, I = this._pids.length
11 while (i < I) {
12 const pid = this._pids[i]
13 printer.say('liveness', { pid })
14 if (!isRunning(pid)) {
15 this.emit('killed', pid)
16 this._pids.splice(i, 1)
17 I--
18 } else {
19 i++
20 }
21 }
22 if (this._pids.length == 0) {
23 this._clean()
24 }
25 await this._unlatched
26 })
27 this.destroyed = false
28 this._pids = []
29 this._exited = {}
30 this._clean()
31 }
32
33 _clean () {
34 this._unlatched = new Promise(resolve => this._latch = resolve)
35 }
36
37 run () {
38 return this._isochronous.start()
39 }
40
41 exited (pid) {
42 assert(this._pids.filter(p => p == pid).length == 0)
43 delete this._exited[pid]
44 }
45
46 unwatch (pid) {
47 const index = this._pids.indexOf(pid)
48 if (~index) {
49 this._pids.splice(index, 1)
50 }
51 delete this._exited[pid]
52 }
53
54 watch (pid) {
55 assert(!this.destroyed)
56 if (this._exited[pid] == null) {
57 this._exited[pid] = pid
58 this._pids.push(pid)
59 this._latch.call()
60 }
61 }
62
63 destroy () {
64 if (!this.destroyed) {
65 this.destroyed = true
66 this._isochronous.stop()
67 this._latch.call()
68 }
69 }
70}
71
72module.exports = Killer