-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
117 lines (91 loc) · 2.21 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
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
115
116
117
'use strict';
const { Thing } = require('abstract-things');
const MachineDetails = require('tinkerhub/machine-details');
const th = require('tinkerhub');
const path = require('path');
const forever = require('forever-monitor');
const Plugins = require('./plugins');
const storage = require('./storage');
class Daemon extends Thing.with(MachineDetails) {
static get type() {
return 'daemon';
}
static availableAPI(builder) {
builder.action('install')
.description('Install a module')
.done();
builder.action('link')
.description('Link a JS file to always run')
.done();
builder.action('plugins')
.done();
}
constructor(packages) {
super();
this.id = 'daemon';
this.metadata.name = 'Tinkerhub Daemon';
this._monitors = new Map();
this._plugins = new Plugins(storage, packages);
process.on('SIGTERM', () => {
this.stopAll()
.then(() => process.exit());
});
}
init() {
return super.init()
.then(() => this._plugins.init())
.then(() => {
for(const p of this._plugins.list()) {
this._start(p);
}
})
.then(() => this);
}
install(pkg) {
return this._plugins.install(pkg)
.then(pkg => this._start(pkg));
}
link(path) {
return this._plugins.link(path)
.then(pkg => this._start(pkg));
}
plugins() {
return this._plugins.list();
}
_start(pkg) {
let monitor = this._monitors.get(pkg.id);
if(monitor) return;
const runner = path.join(__dirname, 'runner.js');
monitor = new forever.Monitor(runner, {
args: [ pkg.path ],
silent: true,
killTree: true,
spinSleepTime: 10000,
minUptime: 2000
});
this._monitors.set(pkg.id, monitor);
monitor.start();
}
stopAll() {
const promises = [];
for(const [ key, monitor ] of this._monitors) {
if(monitor.running && monitor.child) {
promises.push(new Promise(resolve => {
monitor.once('exit', () => {
this._monitors.delete(key);
resolve();
});
monitor.stop();
monitor.forceStop = true;
}));
}
}
return Promise.all(promises);
}
}
const userData = require('./user-data');
new Daemon(userData)
.init()
.then(d => th.register(d))
.catch(err => console.error('Could not start daemon;', err));
process.on('SIGINT', () => process.exit());