dcp-worker 3.2.30-8 → 3.2.30-9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitlab-ci.yml +0 -1
- package/bin/dcp-worker +95 -160
- package/docs/CODEOWNERS +0 -2
- package/etc/dcp-worker-config.js +1 -1
- package/etc/dcp-worker-config.js.md5 +1 -1
- package/lib/blessed-components/index.js +0 -1
- package/lib/blessed-components/log.js +0 -1
- package/lib/blessed-components/sandboxes.js +6 -10
- package/lib/check-scheduler-version.js +0 -1
- package/lib/pidfile.js +1 -1
- package/lib/remote-console.js +2 -10
- package/lib/startWorkerLogger.js +62 -98
- package/lib/worker-loggers/common-types.js +24 -0
- package/lib/worker-loggers/console.js +108 -24
- package/lib/worker-loggers/dashboard.js +172 -32
- package/lib/worker-loggers/event-log.js +60 -28
- package/lib/worker-loggers/logfile.js +83 -57
- package/lib/worker-loggers/syslog.js +63 -41
- package/package.json +6 -15
- package/lib/dashboard-tui.js +0 -231
- package/lib/default-ui-events.js +0 -171
- package/lib/utils.js +0 -28
package/.gitlab-ci.yml
CHANGED
package/bin/dcp-worker
CHANGED
|
@@ -4,26 +4,25 @@
|
|
|
4
4
|
* Standalone NodeJS DCP Worker
|
|
5
5
|
*
|
|
6
6
|
* @author Ryan Rossiter, ryan@kingsds.network
|
|
7
|
-
* Paul, paul@distributive.network
|
|
8
|
-
* Wes Garland, wes@distributive.network
|
|
9
|
-
*
|
|
10
7
|
* @date April 2020
|
|
11
|
-
* April-May 2023
|
|
12
|
-
* May-June 2023
|
|
13
8
|
*/
|
|
14
9
|
'use strict';
|
|
15
10
|
|
|
16
|
-
var worker;
|
|
17
|
-
|
|
18
11
|
const process = require('process');
|
|
19
12
|
const fs = require('fs');
|
|
20
|
-
const path = require('path');
|
|
21
13
|
const crypto = require('crypto');
|
|
22
14
|
const chalk = require('chalk');
|
|
23
|
-
const telnetd = require('../lib/remote-console');
|
|
24
|
-
const utils = require('../lib/utils');
|
|
25
15
|
|
|
26
16
|
const configName = process.env.DCP_CONFIG || '../etc/dcp-worker-config';
|
|
17
|
+
var worker, dcpConfig, debugging;
|
|
18
|
+
|
|
19
|
+
const debug = (...args) => {
|
|
20
|
+
if (!debugging)
|
|
21
|
+
debugging = require('dcp/internal/debugging').scope('dcp-worker');
|
|
22
|
+
if (debugging())
|
|
23
|
+
console.debug('dcp-worker:', ...args);
|
|
24
|
+
};
|
|
25
|
+
|
|
27
26
|
const EXIT_UNHANDLED = 5;
|
|
28
27
|
|
|
29
28
|
/* Setup the telnet REPL up early to ensure early-failure log messages are captured */
|
|
@@ -35,15 +34,13 @@ const replHelpers = {
|
|
|
35
34
|
},
|
|
36
35
|
commands: {
|
|
37
36
|
report: printReport,
|
|
38
|
-
kill:
|
|
37
|
+
kill: process.exit,
|
|
39
38
|
die: () => worker && worker.stop()
|
|
40
39
|
},
|
|
41
40
|
};
|
|
42
|
-
|
|
41
|
+
require('../lib/remote-console').init(replHelpers);
|
|
43
42
|
|
|
44
|
-
/* Initialize dcp-client with local config defaults and run the main function. DCP_CONFIG_COOKIE becomes dcpConfig.cookie.
|
|
45
|
-
* And dcpConfig is defined as a side effect of initializing dcp-client.
|
|
46
|
-
*/
|
|
43
|
+
/* Initialize dcp-client with local config defaults and run the main function. DCP_CONFIG_COOKIE becomes dcpConfig.cookie. */
|
|
47
44
|
process.env.DCP_CONFIG_COOKIE = (Math.random().toString(16)).slice(2) + '-' + process.pid + '-' + Date.now();
|
|
48
45
|
require('dcp-client').init({ configName }).then(main).catch(handleUnhandled);
|
|
49
46
|
|
|
@@ -51,6 +48,7 @@ function parseCliArgs()
|
|
|
51
48
|
{
|
|
52
49
|
var defaultPidFileName;
|
|
53
50
|
|
|
51
|
+
dcpConfig = require('dcp/dcp-config');
|
|
54
52
|
defaultPidFileName = require('../lib/pidfile').getDefaultPidFileName(dcpConfig.worker.pidfile);
|
|
55
53
|
|
|
56
54
|
const cliArgs = require('dcp/cli')
|
|
@@ -69,6 +67,7 @@ function parseCliArgs()
|
|
|
69
67
|
alias: 'd',
|
|
70
68
|
describe: 'default proportion of CPU,GPU to use when cores not specified',
|
|
71
69
|
type: 'string',
|
|
70
|
+
default: JSON.stringify(dcpConfig.worker.defaultCoreDensity),
|
|
72
71
|
},
|
|
73
72
|
verbose: {
|
|
74
73
|
alias: 'v',
|
|
@@ -99,21 +98,18 @@ function parseCliArgs()
|
|
|
99
98
|
},
|
|
100
99
|
priorityOnly: {
|
|
101
100
|
alias: 'P',
|
|
102
|
-
hidden: true,
|
|
103
101
|
describe: 'Set the priority mode [deprecated]',
|
|
104
102
|
type: 'boolean',
|
|
105
103
|
default: false
|
|
106
104
|
},
|
|
107
105
|
'job-id': {
|
|
108
106
|
alias: 'j',
|
|
109
|
-
hidden: true,
|
|
110
107
|
describe: 'Restrict worker to a specific job (use N times for N jobs)',
|
|
111
108
|
type: 'array',
|
|
112
109
|
},
|
|
113
110
|
|
|
114
111
|
join: {
|
|
115
112
|
alias: 'g',
|
|
116
|
-
hidden: true,
|
|
117
113
|
describe: 'Join compute group; the format is "joinKey,joinSecret" or "joinKey,eh1-joinHash"',
|
|
118
114
|
type: 'array'
|
|
119
115
|
},
|
|
@@ -124,27 +120,22 @@ function parseCliArgs()
|
|
|
124
120
|
|
|
125
121
|
leavePublicGroup: {
|
|
126
122
|
type: 'boolean',
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
default: undefined,
|
|
123
|
+
describe: 'Do not fetch slices from public compute group. Ignored if --publicGroupFallback is set',
|
|
124
|
+
default: false,
|
|
130
125
|
},
|
|
131
|
-
|
|
132
126
|
publicGroupFallback: {
|
|
133
|
-
hidden: true,
|
|
134
127
|
describe: 'If set, worker will prefer private groups but fall back on the public group if no preferred work is available',
|
|
135
128
|
type: 'boolean',
|
|
136
|
-
default: '
|
|
137
|
-
defaultDescription:
|
|
129
|
+
default: 'false',
|
|
130
|
+
defaultDescription: false,
|
|
138
131
|
},
|
|
139
132
|
|
|
140
133
|
identityKey: {
|
|
141
|
-
hidden: true,
|
|
142
134
|
describe: 'Identity key, in hex format',
|
|
143
135
|
type: 'string',
|
|
144
136
|
group: 'Identity options',
|
|
145
137
|
},
|
|
146
138
|
identityKeystore: {
|
|
147
|
-
hidden: true,
|
|
148
139
|
describe: 'Identity keystore, in json format',
|
|
149
140
|
type: 'string',
|
|
150
141
|
group: 'Identity options',
|
|
@@ -156,40 +147,30 @@ function parseCliArgs()
|
|
|
156
147
|
group: 'Output options',
|
|
157
148
|
},
|
|
158
149
|
eventDebug: {
|
|
159
|
-
|
|
150
|
+
hide: true,
|
|
160
151
|
describe: 'If set, dump all sandbox and worker events',
|
|
161
152
|
},
|
|
162
153
|
|
|
163
154
|
logfile: {
|
|
164
|
-
describe: 'Path to log file',
|
|
155
|
+
describe: 'Path to log file (if --output=file)',
|
|
165
156
|
type: 'string',
|
|
166
157
|
group: 'Log File output options',
|
|
167
|
-
default: path.resolve('../log/dcp-worker.log'),
|
|
168
158
|
},
|
|
169
159
|
syslogAddress: {
|
|
170
|
-
describe: 'Address of
|
|
160
|
+
describe: 'Address of rsyslog server (if --output=syslog)',
|
|
171
161
|
type: 'string',
|
|
172
162
|
group: 'Syslog output options',
|
|
173
|
-
default: 'loghost',
|
|
174
|
-
},
|
|
175
|
-
syslogFacility: {
|
|
176
|
-
describe: 'Name of syslog facility',
|
|
177
|
-
type: 'string',
|
|
178
|
-
group: 'Syslog output options',
|
|
179
|
-
default: 'local7',
|
|
180
163
|
},
|
|
181
164
|
syslogTransport: {
|
|
182
|
-
describe: 'Transport to connect to
|
|
165
|
+
describe: 'Transport to connect to rsyslog daemon (if --output=syslog)',
|
|
183
166
|
type: 'string',
|
|
184
|
-
choices: ['udp','tcp'
|
|
167
|
+
choices: ['udp','tcp'],
|
|
185
168
|
group: 'Syslog output options',
|
|
186
|
-
default: 'udp',
|
|
187
169
|
},
|
|
188
170
|
syslogPort: {
|
|
189
|
-
describe: 'UDP/TCP port
|
|
171
|
+
describe: 'UDP/TCP port of rsyslog server',
|
|
190
172
|
type: 'number',
|
|
191
173
|
group: 'Syslog output options',
|
|
192
|
-
default: 514,
|
|
193
174
|
},
|
|
194
175
|
|
|
195
176
|
allowedOrigins: {
|
|
@@ -221,8 +202,8 @@ function parseCliArgs()
|
|
|
221
202
|
|
|
222
203
|
if (cliArgs.dumpConfig)
|
|
223
204
|
{
|
|
224
|
-
console.
|
|
225
|
-
|
|
205
|
+
console.debug(JSON.stringify(require('dcp/dcp-config'), null, 2));
|
|
206
|
+
process.exit(0);
|
|
226
207
|
}
|
|
227
208
|
|
|
228
209
|
return cliArgs;
|
|
@@ -247,20 +228,6 @@ function addConfig(target, ...objs)
|
|
|
247
228
|
Object.assign(target, tmp);
|
|
248
229
|
}
|
|
249
230
|
|
|
250
|
-
/**
|
|
251
|
-
* Replacement for process.exit() that tries to increase the probability
|
|
252
|
-
* that remote log messages will make it out over the network.
|
|
253
|
-
*/
|
|
254
|
-
function processExit()
|
|
255
|
-
{
|
|
256
|
-
logClosing('debug', 'Exit Code:', process.exitCode || 0);
|
|
257
|
-
if (console.close)
|
|
258
|
-
console.close();
|
|
259
|
-
setImmediate(() => {
|
|
260
|
-
process.exit.apply(null, arguments);
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
|
|
264
231
|
/**
|
|
265
232
|
* Main program entry point. Assumes DCP client is already initialized and console logging is ready.
|
|
266
233
|
*/
|
|
@@ -268,22 +235,21 @@ async function main()
|
|
|
268
235
|
{
|
|
269
236
|
const wallet = require('dcp/wallet');
|
|
270
237
|
const DCPWorker = require('dcp/worker').Worker;
|
|
238
|
+
const { startWorkerLogger } = require('../lib/startWorkerLogger');
|
|
271
239
|
const cliArgs = parseCliArgs();
|
|
272
240
|
const sawOptions = {
|
|
273
241
|
hostname: cliArgs.hostname,
|
|
274
242
|
port: cliArgs.port
|
|
275
243
|
};
|
|
276
244
|
|
|
277
|
-
|
|
278
|
-
require('../lib/startWorkerLogger').init(cliArgs); /* Start remote logger as early as possible */
|
|
279
|
-
verifyDefaultConfigIntegrity(); /* Bail before TUI & as early as possible if bad conf */
|
|
245
|
+
verifyDefaultConfigIntegrity();
|
|
280
246
|
|
|
281
247
|
process.on('SIGINT', handleSigDeath);
|
|
282
248
|
process.on('SIGTERM', handleSigDeath);
|
|
283
249
|
process.on('SIGQUIT', handleSigDeath);
|
|
284
250
|
process.on('unhandledRejection', handleUnhandled);
|
|
285
251
|
process.on('uncaughtException', handleUnhandled);
|
|
286
|
-
|
|
252
|
+
|
|
287
253
|
let paymentAddress = false
|
|
288
254
|
|| cliArgs.paymentAddress
|
|
289
255
|
|| dcpConfig.worker.paymentAddress
|
|
@@ -294,7 +260,7 @@ async function main()
|
|
|
294
260
|
if (cliArgs.pidFile)
|
|
295
261
|
require('../lib/pidfile').write(cliArgs.pidFile);
|
|
296
262
|
|
|
297
|
-
/* Figure out the worker's identity and put that keystore in the wallet */
|
|
263
|
+
/* Figure out of the worker's identity and put that keystore in the wallet */
|
|
298
264
|
let identityKeystore = false;
|
|
299
265
|
if (cliArgs.identityKey)
|
|
300
266
|
identityKeystore = await new wallet.IdKeystore(cliArgs.identityKey, '');
|
|
@@ -312,14 +278,11 @@ async function main()
|
|
|
312
278
|
* which were derived from dcpConfig in the first place. defaultOptions are overrideable by the usual
|
|
313
279
|
* dcpConfig mechanisms, but since they are dynamic (or non-user-facing) they don't come from the
|
|
314
280
|
* etc/dcp-worker-config.js file that ships with the work.
|
|
315
|
-
*
|
|
316
|
-
* It is important to never disable leavePublicGroup as a side effect of any other operation, or
|
|
317
|
-
* slight configuration errors could have large security impacts.
|
|
318
281
|
*/
|
|
319
282
|
const dcpWorkerOptions = dcpConfig.worker;
|
|
320
283
|
const forceOptions = {
|
|
321
284
|
paymentAddress,
|
|
322
|
-
|
|
285
|
+
leavePublicGroup: cliArgs.leavePublicGroup || dcpConfig.worker.leavePublicGroup || cliArgs.publicGroupFallback || false,
|
|
323
286
|
};
|
|
324
287
|
const defaultOptions = {
|
|
325
288
|
sandboxOptions: {
|
|
@@ -327,21 +290,9 @@ async function main()
|
|
|
327
290
|
},
|
|
328
291
|
};
|
|
329
292
|
|
|
330
|
-
if (cliArgs.leavePublicGroup !== undefined)
|
|
331
|
-
forceOptions.leavePublicGroup = mkBool(cliArgs.leavePublicGroup);
|
|
332
|
-
if (cliArgs.publicGroupFallback !== undefined)
|
|
333
|
-
forceOptions.publicGroupFallback = mkBool(cliArgs.publicGroupFallback);
|
|
334
|
-
|
|
335
293
|
addConfig(dcpWorkerOptions, defaultOptions, dcpConfig.worker, forceOptions);
|
|
336
294
|
processCoresAndDensity(dcpWorkerOptions, cliArgs);
|
|
337
295
|
|
|
338
|
-
/* Support magic value used by Windows screensaver configuration /wg June 2023 */
|
|
339
|
-
if (dcpWorkerOptions.leavePublicGroup === 'fallback')
|
|
340
|
-
{
|
|
341
|
-
dcpWorkerOptions.publicGroupFallback = true;
|
|
342
|
-
dcpWorkerOptions.leavePublicGroup = undefined;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
296
|
/* cliArgs.join is the list of compute groups to join */
|
|
346
297
|
if (cliArgs.join && cliArgs.join.length)
|
|
347
298
|
{
|
|
@@ -374,44 +325,47 @@ async function main()
|
|
|
374
325
|
dcpWorkerOptions.watchdogInterval = cliArgs.watchdogInterval;
|
|
375
326
|
|
|
376
327
|
worker = new DCPWorker(identityKeystore, dcpWorkerOptions);
|
|
377
|
-
worker.on('error',
|
|
378
|
-
worker.on('warning', (...payload) => console.warn
|
|
379
|
-
worker.on('stop', () => { console.log('Worker is stopping') });
|
|
380
|
-
worker.on('end', () => { logClosing('log', 'Worker has stopped') });
|
|
381
|
-
require('../lib/default-ui-events').hook(worker, cliArgs);
|
|
328
|
+
worker.on('error', (...payload) => console.error(...payload));
|
|
329
|
+
worker.on('warning', (...payload) => console.warn(...payload));
|
|
382
330
|
|
|
383
|
-
if (cliArgs.outputMode === 'dashboard')
|
|
384
|
-
require('../lib/dashboard-tui').init(worker, cliArgs);
|
|
385
|
-
|
|
386
331
|
/* Let incorrect event-loop references keep us alive when linked with a debug library, but
|
|
387
332
|
* exit quickly/accurately for production code even when the library isn't perfect.
|
|
388
333
|
*/
|
|
389
334
|
if (require('dcp/build').config.build !== 'debug')
|
|
390
|
-
worker.on('end',
|
|
335
|
+
worker.on('end', process.exit);
|
|
391
336
|
else
|
|
392
|
-
worker.on('end', () => setTimeout(
|
|
337
|
+
worker.on('end', () => setTimeout(process.exit, getCleanupTimeoutMs()).unref());
|
|
393
338
|
|
|
394
339
|
if (cliArgs.eventDebug)
|
|
395
340
|
worker.enableDebugEvents = true;
|
|
396
341
|
|
|
397
|
-
|
|
342
|
+
worker.on('stop', () => { console.log('Worker is stopping') });
|
|
343
|
+
worker.on('end', () => { logClosing('log', 'Worker has stopped') });
|
|
344
|
+
startWorkerLogger(worker, cliArgs);
|
|
345
|
+
|
|
346
|
+
require('../lib/remote-console').setMainEval(function mainEval() { return eval(arguments[0]) });
|
|
347
|
+
|
|
348
|
+
// Activate public group fallback
|
|
349
|
+
// If requested by CLI
|
|
350
|
+
// OR if requested by dcpConfig and not forbidden by the cli
|
|
351
|
+
if (cliArgs.publicGroupFallback
|
|
352
|
+
|| (dcpConfig.worker?.leavePublicGroup === 'fallback'
|
|
353
|
+
&& typeof cliArgs.publicGroupFallback !== false))
|
|
398
354
|
{
|
|
399
|
-
|
|
400
|
-
|
|
355
|
+
dcpWorkerOptions.publicGroupFallback = true;
|
|
356
|
+
|
|
357
|
+
// If local config blocks the public group, then complain instead of activating fallback
|
|
358
|
+
if (dcpConfig.worker?.leavePublicGroup === true)
|
|
359
|
+
{
|
|
360
|
+
console.warn('* Public Group fallback has been requested, but the public group is blocked by local configuration');
|
|
361
|
+
}
|
|
401
362
|
else
|
|
402
363
|
{
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
function fetchEventHandler(ev)
|
|
409
|
-
{
|
|
410
|
-
if (ev instanceof Error)
|
|
411
|
-
console.error('Error fetching task:', ev);
|
|
412
|
-
else
|
|
413
|
-
dcpWorkerOptions.leavePublicGroup = Boolean(utils.slicesFetched(ev) > 0);
|
|
414
|
-
}
|
|
364
|
+
worker.on('fetchend', slicesFetched => {
|
|
365
|
+
// Iff we got work in this fetch, then leave the public group for the
|
|
366
|
+
// next fetch
|
|
367
|
+
dcpConfig.worker.leavePublicGroup = Boolean(slicesFetched > 0);
|
|
368
|
+
});
|
|
415
369
|
}
|
|
416
370
|
}
|
|
417
371
|
|
|
@@ -437,23 +391,21 @@ async function main()
|
|
|
437
391
|
|
|
438
392
|
if (dcpWorkerOptions.jobAddresses?.length > 0)
|
|
439
393
|
introBanner += ` * Processing only ${qty(dcpWorkerOptions.jobAddresses, 'job')} ` + dcpWorkerOptions.jobAddresses.join(', ') + '\n';
|
|
440
|
-
if (dcpWorkerOptions.computeGroups
|
|
394
|
+
if (dcpWorkerOptions.computeGroups?.length > 0)
|
|
441
395
|
introBanner += ` . Joining compute ${qty(dcpWorkerOptions.computeGroups, 'group')} ` + dcpWorkerOptions.computeGroups.map(el => el.joinKey).join(', ') + '\n';
|
|
442
396
|
if (dcpWorkerOptions.publicGroupFallback)
|
|
443
397
|
introBanner += ' . Falling back on public group when preferred groups have no work' + '\n';
|
|
444
|
-
if (dcpWorkerOptions.leavePublicGroup)
|
|
398
|
+
else if (dcpWorkerOptions.leavePublicGroup)
|
|
445
399
|
introBanner += ' . Leaving the public compute group' + '\n';
|
|
446
400
|
if (dcpWorkerOptions.cores)
|
|
447
|
-
introBanner += ` .
|
|
401
|
+
introBanner += ` . Target cores: ${JSON.stringify(dcpWorkerOptions.cores)}\n`;
|
|
448
402
|
else
|
|
449
403
|
introBanner += ` . Target core density: ${JSON.stringify(dcpWorkerOptions.defaultCoreDensity)}\n`;
|
|
450
404
|
if (cliArgs.verbose)
|
|
451
405
|
introBanner += ` + Verbosity level: ${cliArgs.verbose}` + '\n';
|
|
452
406
|
if (cliArgs.eventDebug)
|
|
453
407
|
introBanner += ' + Event debug on' + '\n';
|
|
454
|
-
|
|
455
|
-
introBanner += ` ! telnetd listening on port ${telnetd.port}\n`;
|
|
456
|
-
|
|
408
|
+
|
|
457
409
|
introBanner += ' . Supervisor version: ' + worker.supervisorVersion;
|
|
458
410
|
introBanner += ' . Output mode: ' + cliArgs.outputMode + '\n';
|
|
459
411
|
introBanner += ' * Ready' + '\n';
|
|
@@ -466,7 +418,7 @@ async function main()
|
|
|
466
418
|
if (cliArgs.outputMode !== 'dashboard')
|
|
467
419
|
setInterval(printReport, parseFloat(cliArgs.reportInterval) * 1000).unref();
|
|
468
420
|
else
|
|
469
|
-
console.
|
|
421
|
+
console.log('Ignoring --reportInterval in dashboard output mode');
|
|
470
422
|
}
|
|
471
423
|
|
|
472
424
|
/* Start the worker. Normal process exit happens by virtue of the worker<end> event */
|
|
@@ -493,22 +445,21 @@ function processCoresAndDensity (dcpWorkerOptions, cliArgs)
|
|
|
493
445
|
|
|
494
446
|
const parseArg = (which) => {
|
|
495
447
|
if (!cliArgs[which])
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
}
|
|
448
|
+
return false;
|
|
449
|
+
|
|
450
|
+
const [cpu, gpu] = cliArgs[which].split(',');
|
|
451
|
+
dcpWorkerOptions[which] = { cpu: Number(cpu || defaultTargets[which].cpu),
|
|
452
|
+
gpu: Number(gpu || defaultTargets[which].gpu) };
|
|
453
|
+
return true;
|
|
503
454
|
};
|
|
504
455
|
|
|
505
456
|
parseArg('density');
|
|
506
457
|
parseArg('cores');
|
|
507
458
|
|
|
508
459
|
if (dcpWorkerOptions.cores)
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
460
|
+
debug('cores = ', dcpWorkerOptions.cores);
|
|
461
|
+
else
|
|
462
|
+
debug('core density = ', dcpWorkerOptions.defaultCoreDensity);
|
|
512
463
|
}
|
|
513
464
|
|
|
514
465
|
/**
|
|
@@ -519,7 +470,9 @@ function logClosing(facility, ...message)
|
|
|
519
470
|
{
|
|
520
471
|
var screen = require('../lib/worker-loggers/dashboard').screen;
|
|
521
472
|
|
|
522
|
-
if (screen)
|
|
473
|
+
if (!screen)
|
|
474
|
+
console[facility](message);
|
|
475
|
+
else
|
|
523
476
|
{
|
|
524
477
|
/* Turn off fullscreen TUI and resume "normal" console logging.
|
|
525
478
|
* FUTURE: dashboard API should know how to unregister its hook so that we don't have to clobber
|
|
@@ -528,11 +481,10 @@ function logClosing(facility, ...message)
|
|
|
528
481
|
screen.log(...message);
|
|
529
482
|
screen.destroy();
|
|
530
483
|
screen = false;
|
|
531
|
-
console = new (require('console').Console)(process);
|
|
532
|
-
|
|
484
|
+
console = new (require('console').Console)(process);
|
|
485
|
+
require('../lib/remote-console').reintercept();
|
|
486
|
+
console[facility].call(null, ...message);
|
|
533
487
|
}
|
|
534
|
-
|
|
535
|
-
console[facility](...message);
|
|
536
488
|
}
|
|
537
489
|
|
|
538
490
|
/**
|
|
@@ -541,7 +493,7 @@ function logClosing(facility, ...message)
|
|
|
541
493
|
* the worker must be restarted. This handler does its best to report the rejection and give the worker a few
|
|
542
494
|
* seconds in which to attempt to return slices to the scheduler before it gives up completely.
|
|
543
495
|
*/
|
|
544
|
-
function handleUnhandled(error)
|
|
496
|
+
async function handleUnhandled(error)
|
|
545
497
|
{
|
|
546
498
|
var _worker = worker;
|
|
547
499
|
worker = false;
|
|
@@ -550,21 +502,21 @@ function handleUnhandled(error)
|
|
|
550
502
|
|
|
551
503
|
try
|
|
552
504
|
{
|
|
553
|
-
logClosing(
|
|
554
|
-
} catch(e) {}
|
|
505
|
+
logClosing(error);
|
|
506
|
+
} catch(e) {};
|
|
555
507
|
|
|
556
508
|
if (!_worker)
|
|
557
509
|
console.error('trapped unhandled error:', error)
|
|
558
510
|
else
|
|
559
511
|
{
|
|
560
512
|
console.error('trapped unhandled error -- stopping worker:', error);
|
|
561
|
-
_worker.on('end',
|
|
513
|
+
_worker.on('end', process.exit);
|
|
562
514
|
_worker.stop();
|
|
563
515
|
}
|
|
564
516
|
|
|
565
517
|
setTimeout(() => {
|
|
566
518
|
logClosing('error', 'handleFatalError timeout - exiting now');
|
|
567
|
-
|
|
519
|
+
process.exit();
|
|
568
520
|
}, getCleanupTimeoutMs()).unref();
|
|
569
521
|
|
|
570
522
|
try {
|
|
@@ -574,7 +526,7 @@ function handleUnhandled(error)
|
|
|
574
526
|
fs.appendFileSync(process.env.DCP_WORKER_UNHANDLED_REJECTION_LOG,
|
|
575
527
|
`${Date.now()}: ${error.message}\n${error.stack}\n\n`);
|
|
576
528
|
}
|
|
577
|
-
} catch(e) {}
|
|
529
|
+
} catch(e) {};
|
|
578
530
|
}
|
|
579
531
|
|
|
580
532
|
/** print the slice report via console.log */
|
|
@@ -632,14 +584,14 @@ function sliceReport()
|
|
|
632
584
|
|
|
633
585
|
report += ('Progress:') + '\n';
|
|
634
586
|
worker.workingSandboxes.forEach(sb => {
|
|
635
|
-
const jobName = sb.job
|
|
587
|
+
const jobName = sb.job && sb.job.public && sb.job.public.name || `idek (${sb.jobAddress})`;
|
|
636
588
|
let el = Date.now() - sb.sliceStartTime;
|
|
637
589
|
const t = el < 1000000
|
|
638
590
|
? toInterval(el)
|
|
639
591
|
: 'new';
|
|
640
592
|
|
|
641
593
|
el = sb.progressReports && sb.progressReports.last
|
|
642
|
-
? Date.now() - (sb.sliceStartTime +
|
|
594
|
+
? Date.now() - (sb.sliceStartTime + sb.progressReports.last.timestamp)
|
|
643
595
|
: 0;
|
|
644
596
|
const pct = (typeof sb.progress) === 'number'
|
|
645
597
|
? `${Number(sb.progress).toFixed(0).padStart(2)}%`
|
|
@@ -671,14 +623,14 @@ function handleSigDeath(signalName, signal)
|
|
|
671
623
|
process.off(signalName, handleSigDeath);
|
|
672
624
|
|
|
673
625
|
if (!worker)
|
|
674
|
-
console.
|
|
626
|
+
console.error(`trapped ${signalName}, signal ${signal}`);
|
|
675
627
|
else
|
|
676
628
|
{
|
|
677
|
-
console.
|
|
629
|
+
console.error(`trapped ${signalName}, signal ${signal} -- stopping worker`);
|
|
678
630
|
worker.stop(signalName === 'SIGQUIT');
|
|
679
631
|
}
|
|
680
632
|
|
|
681
|
-
setTimeout(() =>
|
|
633
|
+
setTimeout(() => process.exit(signal - 128), getCleanupTimeoutMs()).unref();
|
|
682
634
|
}
|
|
683
635
|
|
|
684
636
|
/**
|
|
@@ -698,7 +650,7 @@ function getCleanupTimeoutMs()
|
|
|
698
650
|
cleanupTimeout = defaultCT;
|
|
699
651
|
if (!getCleanupTimeoutMs.warned)
|
|
700
652
|
{
|
|
701
|
-
console.
|
|
653
|
+
console.warn(`warning: dcpConfig.worker.cleanupTimeout is not a number (${dcpConfig.worker.cleanupTimeout})`);
|
|
702
654
|
getCleanupTimeoutMs.warned = true;
|
|
703
655
|
}
|
|
704
656
|
}
|
|
@@ -720,14 +672,14 @@ function verifyDefaultConfigIntegrity()
|
|
|
720
672
|
|
|
721
673
|
if (!fs.existsSync(md5sumPath))
|
|
722
674
|
{
|
|
723
|
-
console.
|
|
675
|
+
console.log(chalk.bold.red(` ! warning: ${md5sumPath} not found; cannot verify configuration integrity`));
|
|
724
676
|
require('dcp/utils').sleep(2);
|
|
725
677
|
}
|
|
726
678
|
else
|
|
727
679
|
{
|
|
728
680
|
const originalMd5sum = fs.readFileSync(md5sumPath, 'ascii');
|
|
729
681
|
const actualMd5sum = crypto.createHash('md5')
|
|
730
|
-
.update(fs.readFileSync(workerConfPath))
|
|
682
|
+
.update(fs.readFileSync(workerConfPath, 'ascii'))
|
|
731
683
|
.digest('hex');
|
|
732
684
|
|
|
733
685
|
if (!originalMd5sum.startsWith(actualMd5sum))
|
|
@@ -742,7 +694,7 @@ function verifyDefaultConfigIntegrity()
|
|
|
742
694
|
console.warn(' - the Windows Registry');
|
|
743
695
|
|
|
744
696
|
if (require('dcp/build').config.build !== 'debug')
|
|
745
|
-
|
|
697
|
+
process.exit(1);
|
|
746
698
|
|
|
747
699
|
console.log(chalk.bold.red.inverse("If this wasn't a debug build, the worker would exit now."));
|
|
748
700
|
require('dcp/utils').sleep(2);
|
|
@@ -752,23 +704,6 @@ function verifyDefaultConfigIntegrity()
|
|
|
752
704
|
if (dcpConfig.cookie !== process.env.DCP_CONFIG_COOKIE || !dcpConfig.cookie)
|
|
753
705
|
{
|
|
754
706
|
console.error(' ! DCP Worker default configuration was not loaded; exiting.');
|
|
755
|
-
|
|
707
|
+
process.exit(1);
|
|
756
708
|
}
|
|
757
709
|
}
|
|
758
|
-
|
|
759
|
-
/* thunk - ensures global debugging() symbol always available even if called before dcp-client init */
|
|
760
|
-
function debugging()
|
|
761
|
-
{
|
|
762
|
-
require('dcp-client');
|
|
763
|
-
debugging = require('dcp/internal/debugging').scope('dcp-worker');
|
|
764
|
-
return debugging.apply(this, arguments);
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
/**
|
|
768
|
-
* Cast b to boolean such that 'false' becomes false, falsey things become false, and everything else
|
|
769
|
-
* becomes true.
|
|
770
|
-
*/
|
|
771
|
-
function mkBool(b)
|
|
772
|
-
{
|
|
773
|
-
return Boolean(b) && (b !== 'false');
|
|
774
|
-
}
|
package/docs/CODEOWNERS
CHANGED
|
@@ -18,11 +18,9 @@
|
|
|
18
18
|
/package-lock.json @eroosenmaallen
|
|
19
19
|
|
|
20
20
|
[Wes]
|
|
21
|
-
/npm-hooks/ @wesgarland
|
|
22
21
|
/README.md @wesgarland
|
|
23
22
|
/docs/ @wesgarland
|
|
24
23
|
/.eslintrc.json @wesgarland
|
|
25
|
-
/.npmrc @wesgarland
|
|
26
24
|
/.tidelift @wesgarland
|
|
27
25
|
/lib/ @wesgarland
|
|
28
26
|
/LICENSE.md @wesgarland
|
package/etc/dcp-worker-config.js
CHANGED
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
// keystore('~/.dcp/scott'),
|
|
50
50
|
],
|
|
51
51
|
|
|
52
|
-
jobAddresses:
|
|
52
|
+
jobAddresses: [], /* If specified, restrict the worker to only these jobs */
|
|
53
53
|
paymentAddress: undefined, /* Bank account where earned funds are transfered if not specified on command-line */
|
|
54
54
|
},
|
|
55
55
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
8edf1c57bee521ed7f151a21b8f3f34d
|
|
2
2
|
### DO NOT MODIFY THIS FILE!!! ###
|
|
@@ -67,7 +67,11 @@ class Sandboxes extends Box {
|
|
|
67
67
|
update(data=this.data) {
|
|
68
68
|
this.data = data;
|
|
69
69
|
for (let i = 0; i < this.data.length; i++) {
|
|
70
|
-
|
|
70
|
+
if (i < this.progressBars.length) {
|
|
71
|
+
this.updateProgressBar(i, this.data[i]);
|
|
72
|
+
} else {
|
|
73
|
+
this.createProgressBar();
|
|
74
|
+
}
|
|
71
75
|
}
|
|
72
76
|
|
|
73
77
|
if (this.data.length < this.progressBars.length) {
|
|
@@ -76,15 +80,7 @@ class Sandboxes extends Box {
|
|
|
76
80
|
}
|
|
77
81
|
}
|
|
78
82
|
|
|
79
|
-
this.setLabel(`${this.options.label} (${this.
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Deletes last progress bar
|
|
83
|
-
deleteProgressBar() {
|
|
84
|
-
let i = this.progressBars.length - 1;
|
|
85
|
-
this.progressBars[i].label.destroy()
|
|
86
|
-
this.progressBars[i].progressBar.destroy()
|
|
87
|
-
this.progressBars.pop(i)
|
|
83
|
+
this.setLabel(`${this.options.label} (${this.data.length})`);
|
|
88
84
|
}
|
|
89
85
|
}
|
|
90
86
|
|
package/lib/pidfile.js
CHANGED