dcp-worker 3.2.30-2 → 3.2.30-4
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/bin/dcp-worker +116 -85
- package/docs/CODEOWNERS +2 -0
- package/etc/dcp-worker-config.js +1 -1
- package/etc/dcp-worker-config.js.md5 +1 -1
- package/lib/blessed-components/index.js +1 -0
- package/lib/blessed-components/log.js +1 -0
- package/lib/blessed-components/sandboxes.js +10 -6
- package/lib/check-scheduler-version.js +1 -0
- package/lib/dashboard-tui.js +190 -0
- package/lib/default-ui-events.js +172 -0
- package/lib/pidfile.js +1 -1
- package/lib/remote-console.js +10 -2
- package/lib/startWorkerLogger.js +96 -63
- package/lib/utils.js +28 -0
- package/lib/worker-loggers/console.js +24 -108
- package/lib/worker-loggers/dashboard.js +32 -173
- package/lib/worker-loggers/event-log.js +28 -60
- package/lib/worker-loggers/logfile.js +57 -83
- package/lib/worker-loggers/syslog.js +41 -63
- package/package.json +12 -3
- package/lib/worker-loggers/common-types.js +0 -24
package/bin/dcp-worker
CHANGED
|
@@ -4,25 +4,26 @@
|
|
|
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
|
+
*
|
|
7
10
|
* @date April 2020
|
|
11
|
+
* April-May 2023
|
|
12
|
+
* May-June 2023
|
|
8
13
|
*/
|
|
9
14
|
'use strict';
|
|
10
15
|
|
|
16
|
+
var worker;
|
|
17
|
+
|
|
11
18
|
const process = require('process');
|
|
12
19
|
const fs = require('fs');
|
|
20
|
+
const path = require('path');
|
|
13
21
|
const crypto = require('crypto');
|
|
14
22
|
const chalk = require('chalk');
|
|
23
|
+
const telnetd = require('../lib/remote-console');
|
|
24
|
+
const utils = require('../lib/utils');
|
|
15
25
|
|
|
16
26
|
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
|
-
|
|
26
27
|
const EXIT_UNHANDLED = 5;
|
|
27
28
|
|
|
28
29
|
/* Setup the telnet REPL up early to ensure early-failure log messages are captured */
|
|
@@ -34,13 +35,15 @@ const replHelpers = {
|
|
|
34
35
|
},
|
|
35
36
|
commands: {
|
|
36
37
|
report: printReport,
|
|
37
|
-
kill:
|
|
38
|
+
kill: processExit,
|
|
38
39
|
die: () => worker && worker.stop()
|
|
39
40
|
},
|
|
40
41
|
};
|
|
41
|
-
|
|
42
|
+
telnetd.init(replHelpers);
|
|
42
43
|
|
|
43
|
-
/* Initialize dcp-client with local config defaults and run the main function. DCP_CONFIG_COOKIE becomes dcpConfig.cookie.
|
|
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
|
+
*/
|
|
44
47
|
process.env.DCP_CONFIG_COOKIE = (Math.random().toString(16)).slice(2) + '-' + process.pid + '-' + Date.now();
|
|
45
48
|
require('dcp-client').init({ configName }).then(main).catch(handleUnhandled);
|
|
46
49
|
|
|
@@ -48,7 +51,6 @@ function parseCliArgs()
|
|
|
48
51
|
{
|
|
49
52
|
var defaultPidFileName;
|
|
50
53
|
|
|
51
|
-
dcpConfig = require('dcp/dcp-config');
|
|
52
54
|
defaultPidFileName = require('../lib/pidfile').getDefaultPidFileName(dcpConfig.worker.pidfile);
|
|
53
55
|
|
|
54
56
|
const cliArgs = require('dcp/cli')
|
|
@@ -67,7 +69,6 @@ function parseCliArgs()
|
|
|
67
69
|
alias: 'd',
|
|
68
70
|
describe: 'default proportion of CPU,GPU to use when cores not specified',
|
|
69
71
|
type: 'string',
|
|
70
|
-
default: JSON.stringify(dcpConfig.worker.defaultCoreDensity),
|
|
71
72
|
},
|
|
72
73
|
verbose: {
|
|
73
74
|
alias: 'v',
|
|
@@ -98,18 +99,21 @@ function parseCliArgs()
|
|
|
98
99
|
},
|
|
99
100
|
priorityOnly: {
|
|
100
101
|
alias: 'P',
|
|
102
|
+
hidden: true,
|
|
101
103
|
describe: 'Set the priority mode [deprecated]',
|
|
102
104
|
type: 'boolean',
|
|
103
105
|
default: false
|
|
104
106
|
},
|
|
105
107
|
'job-id': {
|
|
106
108
|
alias: 'j',
|
|
109
|
+
hidden: true,
|
|
107
110
|
describe: 'Restrict worker to a specific job (use N times for N jobs)',
|
|
108
111
|
type: 'array',
|
|
109
112
|
},
|
|
110
113
|
|
|
111
114
|
join: {
|
|
112
115
|
alias: 'g',
|
|
116
|
+
hidden: true,
|
|
113
117
|
describe: 'Join compute group; the format is "joinKey,joinSecret" or "joinKey,eh1-joinHash"',
|
|
114
118
|
type: 'array'
|
|
115
119
|
},
|
|
@@ -120,22 +124,27 @@ function parseCliArgs()
|
|
|
120
124
|
|
|
121
125
|
leavePublicGroup: {
|
|
122
126
|
type: 'boolean',
|
|
127
|
+
hidden: true,
|
|
123
128
|
describe: 'Do not fetch slices from public compute group.',
|
|
124
129
|
default: undefined,
|
|
125
130
|
},
|
|
126
131
|
|
|
127
132
|
publicGroupFallback: {
|
|
133
|
+
hidden: true,
|
|
128
134
|
describe: 'If set, worker will prefer private groups but fall back on the public group if no preferred work is available',
|
|
129
135
|
type: 'boolean',
|
|
130
|
-
default: undefined,
|
|
136
|
+
default: 'undefined',
|
|
137
|
+
defaultDescription: undefined,
|
|
131
138
|
},
|
|
132
139
|
|
|
133
140
|
identityKey: {
|
|
141
|
+
hidden: true,
|
|
134
142
|
describe: 'Identity key, in hex format',
|
|
135
143
|
type: 'string',
|
|
136
144
|
group: 'Identity options',
|
|
137
145
|
},
|
|
138
146
|
identityKeystore: {
|
|
147
|
+
hidden: true,
|
|
139
148
|
describe: 'Identity keystore, in json format',
|
|
140
149
|
type: 'string',
|
|
141
150
|
group: 'Identity options',
|
|
@@ -147,30 +156,40 @@ function parseCliArgs()
|
|
|
147
156
|
group: 'Output options',
|
|
148
157
|
},
|
|
149
158
|
eventDebug: {
|
|
150
|
-
|
|
159
|
+
hidden: true,
|
|
151
160
|
describe: 'If set, dump all sandbox and worker events',
|
|
152
161
|
},
|
|
153
162
|
|
|
154
163
|
logfile: {
|
|
155
|
-
describe: 'Path to log file
|
|
164
|
+
describe: 'Path to log file',
|
|
156
165
|
type: 'string',
|
|
157
166
|
group: 'Log File output options',
|
|
167
|
+
default: path.resolve('../log/dcp-worker.log'),
|
|
158
168
|
},
|
|
159
169
|
syslogAddress: {
|
|
160
|
-
describe: 'Address of
|
|
170
|
+
describe: 'Address of syslog server',
|
|
171
|
+
type: 'string',
|
|
172
|
+
group: 'Syslog output options',
|
|
173
|
+
default: 'loghost',
|
|
174
|
+
},
|
|
175
|
+
syslogFacility: {
|
|
176
|
+
describe: 'Name of syslog facility',
|
|
161
177
|
type: 'string',
|
|
162
178
|
group: 'Syslog output options',
|
|
179
|
+
default: 'local7',
|
|
163
180
|
},
|
|
164
181
|
syslogTransport: {
|
|
165
|
-
describe: 'Transport to connect to
|
|
182
|
+
describe: 'Transport to connect to use for syslog',
|
|
166
183
|
type: 'string',
|
|
167
|
-
choices: ['udp','tcp'],
|
|
184
|
+
choices: ['udp','tcp','unix','tls'],
|
|
168
185
|
group: 'Syslog output options',
|
|
186
|
+
default: 'udp',
|
|
169
187
|
},
|
|
170
188
|
syslogPort: {
|
|
171
|
-
describe: 'UDP/TCP port
|
|
189
|
+
describe: 'UDP/TCP port to use for syslog',
|
|
172
190
|
type: 'number',
|
|
173
191
|
group: 'Syslog output options',
|
|
192
|
+
default: 514,
|
|
174
193
|
},
|
|
175
194
|
|
|
176
195
|
allowedOrigins: {
|
|
@@ -202,8 +221,8 @@ function parseCliArgs()
|
|
|
202
221
|
|
|
203
222
|
if (cliArgs.dumpConfig)
|
|
204
223
|
{
|
|
205
|
-
console.
|
|
206
|
-
|
|
224
|
+
console.log(JSON.stringify(require('dcp/dcp-config'), null, 2));
|
|
225
|
+
processExit(0);
|
|
207
226
|
}
|
|
208
227
|
|
|
209
228
|
return cliArgs;
|
|
@@ -228,6 +247,20 @@ function addConfig(target, ...objs)
|
|
|
228
247
|
Object.assign(target, tmp);
|
|
229
248
|
}
|
|
230
249
|
|
|
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
|
+
|
|
231
264
|
/**
|
|
232
265
|
* Main program entry point. Assumes DCP client is already initialized and console logging is ready.
|
|
233
266
|
*/
|
|
@@ -235,21 +268,22 @@ async function main()
|
|
|
235
268
|
{
|
|
236
269
|
const wallet = require('dcp/wallet');
|
|
237
270
|
const DCPWorker = require('dcp/worker').Worker;
|
|
238
|
-
const { startWorkerLogger } = require('../lib/startWorkerLogger');
|
|
239
271
|
const cliArgs = parseCliArgs();
|
|
240
272
|
const sawOptions = {
|
|
241
273
|
hostname: cliArgs.hostname,
|
|
242
274
|
port: cliArgs.port
|
|
243
275
|
};
|
|
244
276
|
|
|
245
|
-
|
|
277
|
+
telnetd.setMainEval(function mainEval() { return eval(arguments[0]) }); // eslint-disable-line no-eval
|
|
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 */
|
|
246
280
|
|
|
247
281
|
process.on('SIGINT', handleSigDeath);
|
|
248
282
|
process.on('SIGTERM', handleSigDeath);
|
|
249
283
|
process.on('SIGQUIT', handleSigDeath);
|
|
250
284
|
process.on('unhandledRejection', handleUnhandled);
|
|
251
285
|
process.on('uncaughtException', handleUnhandled);
|
|
252
|
-
|
|
286
|
+
|
|
253
287
|
let paymentAddress = false
|
|
254
288
|
|| cliArgs.paymentAddress
|
|
255
289
|
|| dcpConfig.worker.paymentAddress
|
|
@@ -285,6 +319,7 @@ async function main()
|
|
|
285
319
|
const dcpWorkerOptions = dcpConfig.worker;
|
|
286
320
|
const forceOptions = {
|
|
287
321
|
paymentAddress,
|
|
322
|
+
maxWorkingSandboxes: cliArgs.cores,
|
|
288
323
|
};
|
|
289
324
|
const defaultOptions = {
|
|
290
325
|
sandboxOptions: {
|
|
@@ -339,27 +374,26 @@ async function main()
|
|
|
339
374
|
dcpWorkerOptions.watchdogInterval = cliArgs.watchdogInterval;
|
|
340
375
|
|
|
341
376
|
worker = new DCPWorker(identityKeystore, dcpWorkerOptions);
|
|
342
|
-
worker.on('error',
|
|
343
|
-
worker.on('warning', (...payload) => console.warn(...payload));
|
|
377
|
+
worker.on('error', (...payload) => console.error(...payload));
|
|
378
|
+
worker.on('warning', (...payload) => console.warn (...payload));
|
|
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);
|
|
344
382
|
|
|
383
|
+
if (cliArgs.outputMode === 'dashboard')
|
|
384
|
+
require('../lib/dashboard-tui').init(worker, cliArgs);
|
|
385
|
+
|
|
345
386
|
/* Let incorrect event-loop references keep us alive when linked with a debug library, but
|
|
346
387
|
* exit quickly/accurately for production code even when the library isn't perfect.
|
|
347
388
|
*/
|
|
348
389
|
if (require('dcp/build').config.build !== 'debug')
|
|
349
|
-
worker.on('end',
|
|
390
|
+
worker.on('end', processExit);
|
|
350
391
|
else
|
|
351
|
-
worker.on('end', () => setTimeout(
|
|
392
|
+
worker.on('end', () => setTimeout(processExit, getCleanupTimeoutMs()).unref());
|
|
352
393
|
|
|
353
394
|
if (cliArgs.eventDebug)
|
|
354
395
|
worker.enableDebugEvents = true;
|
|
355
396
|
|
|
356
|
-
worker.on('stop', () => { console.log('Worker is stopping') });
|
|
357
|
-
worker.on('end', () => { logClosing('log', 'Worker has stopped') });
|
|
358
|
-
startWorkerLogger(worker, cliArgs);
|
|
359
|
-
|
|
360
|
-
require('../lib/remote-console').setMainEval(function mainEval() { return eval(arguments[0]) });
|
|
361
|
-
require('../lib/remote-console').reintercept();
|
|
362
|
-
|
|
363
397
|
if (dcpWorkerOptions.publicGroupFallback)
|
|
364
398
|
{
|
|
365
399
|
if (dcpWorkerOptions.leavePublicGroup)
|
|
@@ -373,23 +407,10 @@ async function main()
|
|
|
373
407
|
|
|
374
408
|
function fetchEventHandler(ev)
|
|
375
409
|
{
|
|
376
|
-
var slicesFetched;
|
|
377
|
-
|
|
378
410
|
if (ev instanceof Error)
|
|
379
|
-
{
|
|
380
411
|
console.error('Error fetching task:', ev);
|
|
381
|
-
return;
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
if (typeof ev === 'string') /* <= June 2023 Worker events: remove ~ Sep 2023 /wg */
|
|
385
|
-
slicesFetched = ev;
|
|
386
412
|
else
|
|
387
|
-
|
|
388
|
-
const task = ev;
|
|
389
|
-
slicesFetched = task.slices?.length;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
dcpWorkerOptions.leavePublicGroup = Boolean(slicesFetched > 0);
|
|
413
|
+
dcpWorkerOptions.leavePublicGroup = Boolean(utils.slicesFetched(ev) > 0);
|
|
393
414
|
}
|
|
394
415
|
}
|
|
395
416
|
}
|
|
@@ -416,21 +437,23 @@ async function main()
|
|
|
416
437
|
|
|
417
438
|
if (dcpWorkerOptions.jobAddresses?.length > 0)
|
|
418
439
|
introBanner += ` * Processing only ${qty(dcpWorkerOptions.jobAddresses, 'job')} ` + dcpWorkerOptions.jobAddresses.join(', ') + '\n';
|
|
419
|
-
if (dcpWorkerOptions.computeGroups
|
|
440
|
+
if (dcpWorkerOptions.computeGroups && Object.keys(dcpWorkerOptions.computeGroups).length > 0)
|
|
420
441
|
introBanner += ` . Joining compute ${qty(dcpWorkerOptions.computeGroups, 'group')} ` + dcpWorkerOptions.computeGroups.map(el => el.joinKey).join(', ') + '\n';
|
|
421
442
|
if (dcpWorkerOptions.publicGroupFallback)
|
|
422
443
|
introBanner += ' . Falling back on public group when preferred groups have no work' + '\n';
|
|
423
444
|
if (dcpWorkerOptions.leavePublicGroup)
|
|
424
445
|
introBanner += ' . Leaving the public compute group' + '\n';
|
|
425
446
|
if (dcpWorkerOptions.cores)
|
|
426
|
-
introBanner += ` .
|
|
447
|
+
introBanner += ` . Configured Cores: ${dcpWorkerOptions.cores.cpu},${dcpWorkerOptions.cores.gpu}\n`
|
|
427
448
|
else
|
|
428
449
|
introBanner += ` . Target core density: ${JSON.stringify(dcpWorkerOptions.defaultCoreDensity)}\n`;
|
|
429
450
|
if (cliArgs.verbose)
|
|
430
451
|
introBanner += ` + Verbosity level: ${cliArgs.verbose}` + '\n';
|
|
431
452
|
if (cliArgs.eventDebug)
|
|
432
453
|
introBanner += ' + Event debug on' + '\n';
|
|
433
|
-
|
|
454
|
+
if (telnetd.hasOwnProperty('port'))
|
|
455
|
+
introBanner += ` ! telnetd listening on port ${telnetd.port}\n`;
|
|
456
|
+
|
|
434
457
|
introBanner += ' . Supervisor version: ' + worker.supervisorVersion;
|
|
435
458
|
introBanner += ' . Output mode: ' + cliArgs.outputMode + '\n';
|
|
436
459
|
introBanner += ' * Ready' + '\n';
|
|
@@ -443,7 +466,7 @@ async function main()
|
|
|
443
466
|
if (cliArgs.outputMode !== 'dashboard')
|
|
444
467
|
setInterval(printReport, parseFloat(cliArgs.reportInterval) * 1000).unref();
|
|
445
468
|
else
|
|
446
|
-
console.
|
|
469
|
+
console.warn('Ignoring --reportInterval in dashboard output mode');
|
|
447
470
|
}
|
|
448
471
|
|
|
449
472
|
/* Start the worker. Normal process exit happens by virtue of the worker<end> event */
|
|
@@ -470,21 +493,22 @@ function processCoresAndDensity (dcpWorkerOptions, cliArgs)
|
|
|
470
493
|
|
|
471
494
|
const parseArg = (which) => {
|
|
472
495
|
if (!cliArgs[which])
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
496
|
+
dcpWorkerOptions[which] = defaultTargets[which];
|
|
497
|
+
else
|
|
498
|
+
{
|
|
499
|
+
const [cpu, gpu] = cliArgs[which].split(',');
|
|
500
|
+
dcpWorkerOptions[which] = { cpu: Number(cpu || defaultTargets[which].cpu),
|
|
501
|
+
gpu: Number(gpu || defaultTargets[which].gpu) };
|
|
502
|
+
}
|
|
479
503
|
};
|
|
480
504
|
|
|
481
505
|
parseArg('density');
|
|
482
506
|
parseArg('cores');
|
|
483
507
|
|
|
484
508
|
if (dcpWorkerOptions.cores)
|
|
485
|
-
debug('cores =
|
|
486
|
-
|
|
487
|
-
debug('core density =
|
|
509
|
+
debugging() && console.debug('dcp-worker: cores =', dcpWorkerOptions.cores);
|
|
510
|
+
if (dcpWorkerOptions.density)
|
|
511
|
+
debugging() && console.debug('dcp-worker: core density =', dcpWorkerOptions.density);
|
|
488
512
|
}
|
|
489
513
|
|
|
490
514
|
/**
|
|
@@ -495,9 +519,7 @@ function logClosing(facility, ...message)
|
|
|
495
519
|
{
|
|
496
520
|
var screen = require('../lib/worker-loggers/dashboard').screen;
|
|
497
521
|
|
|
498
|
-
if (
|
|
499
|
-
console[facility](message);
|
|
500
|
-
else
|
|
522
|
+
if (screen)
|
|
501
523
|
{
|
|
502
524
|
/* Turn off fullscreen TUI and resume "normal" console logging.
|
|
503
525
|
* FUTURE: dashboard API should know how to unregister its hook so that we don't have to clobber
|
|
@@ -506,10 +528,11 @@ function logClosing(facility, ...message)
|
|
|
506
528
|
screen.log(...message);
|
|
507
529
|
screen.destroy();
|
|
508
530
|
screen = false;
|
|
509
|
-
console = new (require('console').Console)(process);
|
|
510
|
-
|
|
511
|
-
console[facility].call(null, ...message);
|
|
531
|
+
console = new (require('console').Console)(process); // eslint-disable-line no-global-assign
|
|
532
|
+
telnetd.reintercept();
|
|
512
533
|
}
|
|
534
|
+
|
|
535
|
+
console[facility](...message);
|
|
513
536
|
}
|
|
514
537
|
|
|
515
538
|
/**
|
|
@@ -518,7 +541,7 @@ function logClosing(facility, ...message)
|
|
|
518
541
|
* the worker must be restarted. This handler does its best to report the rejection and give the worker a few
|
|
519
542
|
* seconds in which to attempt to return slices to the scheduler before it gives up completely.
|
|
520
543
|
*/
|
|
521
|
-
|
|
544
|
+
function handleUnhandled(error)
|
|
522
545
|
{
|
|
523
546
|
var _worker = worker;
|
|
524
547
|
worker = false;
|
|
@@ -527,21 +550,21 @@ async function handleUnhandled(error)
|
|
|
527
550
|
|
|
528
551
|
try
|
|
529
552
|
{
|
|
530
|
-
logClosing(error);
|
|
531
|
-
} catch(e) {}
|
|
553
|
+
logClosing('error', error);
|
|
554
|
+
} catch(e) {} // eslint-disable-line no-empty
|
|
532
555
|
|
|
533
556
|
if (!_worker)
|
|
534
557
|
console.error('trapped unhandled error:', error)
|
|
535
558
|
else
|
|
536
559
|
{
|
|
537
560
|
console.error('trapped unhandled error -- stopping worker:', error);
|
|
538
|
-
_worker.on('end',
|
|
561
|
+
_worker.on('end', processExit);
|
|
539
562
|
_worker.stop();
|
|
540
563
|
}
|
|
541
564
|
|
|
542
565
|
setTimeout(() => {
|
|
543
566
|
logClosing('error', 'handleFatalError timeout - exiting now');
|
|
544
|
-
|
|
567
|
+
processExit();
|
|
545
568
|
}, getCleanupTimeoutMs()).unref();
|
|
546
569
|
|
|
547
570
|
try {
|
|
@@ -551,7 +574,7 @@ async function handleUnhandled(error)
|
|
|
551
574
|
fs.appendFileSync(process.env.DCP_WORKER_UNHANDLED_REJECTION_LOG,
|
|
552
575
|
`${Date.now()}: ${error.message}\n${error.stack}\n\n`);
|
|
553
576
|
}
|
|
554
|
-
} catch(e) {}
|
|
577
|
+
} catch(e) {} // eslint-disable-line no-empty
|
|
555
578
|
}
|
|
556
579
|
|
|
557
580
|
/** print the slice report via console.log */
|
|
@@ -609,14 +632,14 @@ function sliceReport()
|
|
|
609
632
|
|
|
610
633
|
report += ('Progress:') + '\n';
|
|
611
634
|
worker.workingSandboxes.forEach(sb => {
|
|
612
|
-
const jobName = sb.job
|
|
635
|
+
const jobName = sb.job?.public?.name || `idek (${sb.jobAddress})`;
|
|
613
636
|
let el = Date.now() - sb.sliceStartTime;
|
|
614
637
|
const t = el < 1000000
|
|
615
638
|
? toInterval(el)
|
|
616
639
|
: 'new';
|
|
617
640
|
|
|
618
641
|
el = sb.progressReports && sb.progressReports.last
|
|
619
|
-
? Date.now() - (sb.sliceStartTime + sb.progressReports.last
|
|
642
|
+
? Date.now() - (sb.sliceStartTime + (sb.progressReports.last?.timestamp ?? 0))
|
|
620
643
|
: 0;
|
|
621
644
|
const pct = (typeof sb.progress) === 'number'
|
|
622
645
|
? `${Number(sb.progress).toFixed(0).padStart(2)}%`
|
|
@@ -648,14 +671,14 @@ function handleSigDeath(signalName, signal)
|
|
|
648
671
|
process.off(signalName, handleSigDeath);
|
|
649
672
|
|
|
650
673
|
if (!worker)
|
|
651
|
-
console.
|
|
674
|
+
console.warn(`trapped ${signalName}, signal ${signal}`);
|
|
652
675
|
else
|
|
653
676
|
{
|
|
654
|
-
console.
|
|
677
|
+
console.warn(`trapped ${signalName}, signal ${signal} -- stopping worker`);
|
|
655
678
|
worker.stop(signalName === 'SIGQUIT');
|
|
656
679
|
}
|
|
657
680
|
|
|
658
|
-
setTimeout(() =>
|
|
681
|
+
setTimeout(() => processExit(signal - 128), getCleanupTimeoutMs()).unref();
|
|
659
682
|
}
|
|
660
683
|
|
|
661
684
|
/**
|
|
@@ -675,7 +698,7 @@ function getCleanupTimeoutMs()
|
|
|
675
698
|
cleanupTimeout = defaultCT;
|
|
676
699
|
if (!getCleanupTimeoutMs.warned)
|
|
677
700
|
{
|
|
678
|
-
console.
|
|
701
|
+
console.error(`warning: dcpConfig.worker.cleanupTimeout is not a number (${dcpConfig.worker.cleanupTimeout})`);
|
|
679
702
|
getCleanupTimeoutMs.warned = true;
|
|
680
703
|
}
|
|
681
704
|
}
|
|
@@ -697,7 +720,7 @@ function verifyDefaultConfigIntegrity()
|
|
|
697
720
|
|
|
698
721
|
if (!fs.existsSync(md5sumPath))
|
|
699
722
|
{
|
|
700
|
-
console.
|
|
723
|
+
console.error(chalk.bold.red(` ! warning: ${md5sumPath} not found; cannot verify configuration integrity`));
|
|
701
724
|
require('dcp/utils').sleep(2);
|
|
702
725
|
}
|
|
703
726
|
else
|
|
@@ -719,7 +742,7 @@ function verifyDefaultConfigIntegrity()
|
|
|
719
742
|
console.warn(' - the Windows Registry');
|
|
720
743
|
|
|
721
744
|
if (require('dcp/build').config.build !== 'debug')
|
|
722
|
-
|
|
745
|
+
processExit(1);
|
|
723
746
|
|
|
724
747
|
console.log(chalk.bold.red.inverse("If this wasn't a debug build, the worker would exit now."));
|
|
725
748
|
require('dcp/utils').sleep(2);
|
|
@@ -729,10 +752,18 @@ function verifyDefaultConfigIntegrity()
|
|
|
729
752
|
if (dcpConfig.cookie !== process.env.DCP_CONFIG_COOKIE || !dcpConfig.cookie)
|
|
730
753
|
{
|
|
731
754
|
console.error(' ! DCP Worker default configuration was not loaded; exiting.');
|
|
732
|
-
|
|
755
|
+
processExit(1);
|
|
733
756
|
}
|
|
734
757
|
}
|
|
735
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
|
+
|
|
736
767
|
/**
|
|
737
768
|
* Cast b to boolean such that 'false' becomes false, falsey things become false, and everything else
|
|
738
769
|
* becomes true.
|
package/docs/CODEOWNERS
CHANGED
|
@@ -18,9 +18,11 @@
|
|
|
18
18
|
/package-lock.json @eroosenmaallen
|
|
19
19
|
|
|
20
20
|
[Wes]
|
|
21
|
+
/npm-hooks/ @wesgarland
|
|
21
22
|
/README.md @wesgarland
|
|
22
23
|
/docs/ @wesgarland
|
|
23
24
|
/.eslintrc.json @wesgarland
|
|
25
|
+
/.npmrc @wesgarland
|
|
24
26
|
/.tidelift @wesgarland
|
|
25
27
|
/lib/ @wesgarland
|
|
26
28
|
/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: false, /* 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
|
+
4d49057dd014344e4be5a266e9754824
|
|
2
2
|
### DO NOT MODIFY THIS FILE!!! ###
|
|
@@ -67,11 +67,7 @@ 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
|
-
|
|
71
|
-
this.updateProgressBar(i, this.data[i]);
|
|
72
|
-
} else {
|
|
73
|
-
this.createProgressBar();
|
|
74
|
-
}
|
|
70
|
+
this.updateProgressBar(i, this.data[i]);
|
|
75
71
|
}
|
|
76
72
|
|
|
77
73
|
if (this.data.length < this.progressBars.length) {
|
|
@@ -80,7 +76,15 @@ class Sandboxes extends Box {
|
|
|
80
76
|
}
|
|
81
77
|
}
|
|
82
78
|
|
|
83
|
-
this.setLabel(`${this.options.label} (${this.
|
|
79
|
+
this.setLabel(`${this.options.label} (${this.progressBars.length})`);
|
|
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)
|
|
84
88
|
}
|
|
85
89
|
}
|
|
86
90
|
|