dcp-worker 3.2.30-1 → 3.2.30-11
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 -84
- 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 +231 -0
- package/lib/default-ui-events.js +171 -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 -172
- 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 +14 -5
- 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,26 +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
|
-
|
|
362
397
|
if (dcpWorkerOptions.publicGroupFallback)
|
|
363
398
|
{
|
|
364
399
|
if (dcpWorkerOptions.leavePublicGroup)
|
|
@@ -372,23 +407,10 @@ async function main()
|
|
|
372
407
|
|
|
373
408
|
function fetchEventHandler(ev)
|
|
374
409
|
{
|
|
375
|
-
var slicesFetched;
|
|
376
|
-
|
|
377
410
|
if (ev instanceof Error)
|
|
378
|
-
{
|
|
379
411
|
console.error('Error fetching task:', ev);
|
|
380
|
-
return;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
if (typeof ev === 'string') /* <= June 2023 Worker events: remove ~ Sep 2023 /wg */
|
|
384
|
-
slicesFetched = ev;
|
|
385
412
|
else
|
|
386
|
-
|
|
387
|
-
const task = ev;
|
|
388
|
-
slicesFetched = task.slices?.length;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
dcpWorkerOptions.leavePublicGroup = Boolean(slicesFetched > 0);
|
|
413
|
+
dcpWorkerOptions.leavePublicGroup = Boolean(utils.slicesFetched(ev) > 0);
|
|
392
414
|
}
|
|
393
415
|
}
|
|
394
416
|
}
|
|
@@ -415,21 +437,23 @@ async function main()
|
|
|
415
437
|
|
|
416
438
|
if (dcpWorkerOptions.jobAddresses?.length > 0)
|
|
417
439
|
introBanner += ` * Processing only ${qty(dcpWorkerOptions.jobAddresses, 'job')} ` + dcpWorkerOptions.jobAddresses.join(', ') + '\n';
|
|
418
|
-
if (dcpWorkerOptions.computeGroups
|
|
440
|
+
if (dcpWorkerOptions.computeGroups && Object.keys(dcpWorkerOptions.computeGroups).length > 0)
|
|
419
441
|
introBanner += ` . Joining compute ${qty(dcpWorkerOptions.computeGroups, 'group')} ` + dcpWorkerOptions.computeGroups.map(el => el.joinKey).join(', ') + '\n';
|
|
420
442
|
if (dcpWorkerOptions.publicGroupFallback)
|
|
421
443
|
introBanner += ' . Falling back on public group when preferred groups have no work' + '\n';
|
|
422
444
|
if (dcpWorkerOptions.leavePublicGroup)
|
|
423
445
|
introBanner += ' . Leaving the public compute group' + '\n';
|
|
424
446
|
if (dcpWorkerOptions.cores)
|
|
425
|
-
introBanner += ` .
|
|
447
|
+
introBanner += ` . Configured Cores: ${dcpWorkerOptions.cores.cpu},${dcpWorkerOptions.cores.gpu}\n`
|
|
426
448
|
else
|
|
427
449
|
introBanner += ` . Target core density: ${JSON.stringify(dcpWorkerOptions.defaultCoreDensity)}\n`;
|
|
428
450
|
if (cliArgs.verbose)
|
|
429
451
|
introBanner += ` + Verbosity level: ${cliArgs.verbose}` + '\n';
|
|
430
452
|
if (cliArgs.eventDebug)
|
|
431
453
|
introBanner += ' + Event debug on' + '\n';
|
|
432
|
-
|
|
454
|
+
if (telnetd.hasOwnProperty('port'))
|
|
455
|
+
introBanner += ` ! telnetd listening on port ${telnetd.port}\n`;
|
|
456
|
+
|
|
433
457
|
introBanner += ' . Supervisor version: ' + worker.supervisorVersion;
|
|
434
458
|
introBanner += ' . Output mode: ' + cliArgs.outputMode + '\n';
|
|
435
459
|
introBanner += ' * Ready' + '\n';
|
|
@@ -442,7 +466,7 @@ async function main()
|
|
|
442
466
|
if (cliArgs.outputMode !== 'dashboard')
|
|
443
467
|
setInterval(printReport, parseFloat(cliArgs.reportInterval) * 1000).unref();
|
|
444
468
|
else
|
|
445
|
-
console.
|
|
469
|
+
console.warn('Ignoring --reportInterval in dashboard output mode');
|
|
446
470
|
}
|
|
447
471
|
|
|
448
472
|
/* Start the worker. Normal process exit happens by virtue of the worker<end> event */
|
|
@@ -469,21 +493,22 @@ function processCoresAndDensity (dcpWorkerOptions, cliArgs)
|
|
|
469
493
|
|
|
470
494
|
const parseArg = (which) => {
|
|
471
495
|
if (!cliArgs[which])
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
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
|
+
}
|
|
478
503
|
};
|
|
479
504
|
|
|
480
505
|
parseArg('density');
|
|
481
506
|
parseArg('cores');
|
|
482
507
|
|
|
483
508
|
if (dcpWorkerOptions.cores)
|
|
484
|
-
debug('cores =
|
|
485
|
-
|
|
486
|
-
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);
|
|
487
512
|
}
|
|
488
513
|
|
|
489
514
|
/**
|
|
@@ -494,9 +519,7 @@ function logClosing(facility, ...message)
|
|
|
494
519
|
{
|
|
495
520
|
var screen = require('../lib/worker-loggers/dashboard').screen;
|
|
496
521
|
|
|
497
|
-
if (
|
|
498
|
-
console[facility](message);
|
|
499
|
-
else
|
|
522
|
+
if (screen)
|
|
500
523
|
{
|
|
501
524
|
/* Turn off fullscreen TUI and resume "normal" console logging.
|
|
502
525
|
* FUTURE: dashboard API should know how to unregister its hook so that we don't have to clobber
|
|
@@ -505,10 +528,11 @@ function logClosing(facility, ...message)
|
|
|
505
528
|
screen.log(...message);
|
|
506
529
|
screen.destroy();
|
|
507
530
|
screen = false;
|
|
508
|
-
console = new (require('console').Console)(process);
|
|
509
|
-
|
|
510
|
-
console[facility].call(null, ...message);
|
|
531
|
+
console = new (require('console').Console)(process); // eslint-disable-line no-global-assign
|
|
532
|
+
telnetd.reintercept();
|
|
511
533
|
}
|
|
534
|
+
|
|
535
|
+
console[facility](...message);
|
|
512
536
|
}
|
|
513
537
|
|
|
514
538
|
/**
|
|
@@ -517,7 +541,7 @@ function logClosing(facility, ...message)
|
|
|
517
541
|
* the worker must be restarted. This handler does its best to report the rejection and give the worker a few
|
|
518
542
|
* seconds in which to attempt to return slices to the scheduler before it gives up completely.
|
|
519
543
|
*/
|
|
520
|
-
|
|
544
|
+
function handleUnhandled(error)
|
|
521
545
|
{
|
|
522
546
|
var _worker = worker;
|
|
523
547
|
worker = false;
|
|
@@ -526,21 +550,21 @@ async function handleUnhandled(error)
|
|
|
526
550
|
|
|
527
551
|
try
|
|
528
552
|
{
|
|
529
|
-
logClosing(error);
|
|
530
|
-
} catch(e) {}
|
|
553
|
+
logClosing('error', error);
|
|
554
|
+
} catch(e) {} // eslint-disable-line no-empty
|
|
531
555
|
|
|
532
556
|
if (!_worker)
|
|
533
557
|
console.error('trapped unhandled error:', error)
|
|
534
558
|
else
|
|
535
559
|
{
|
|
536
560
|
console.error('trapped unhandled error -- stopping worker:', error);
|
|
537
|
-
_worker.on('end',
|
|
561
|
+
_worker.on('end', processExit);
|
|
538
562
|
_worker.stop();
|
|
539
563
|
}
|
|
540
564
|
|
|
541
565
|
setTimeout(() => {
|
|
542
566
|
logClosing('error', 'handleFatalError timeout - exiting now');
|
|
543
|
-
|
|
567
|
+
processExit();
|
|
544
568
|
}, getCleanupTimeoutMs()).unref();
|
|
545
569
|
|
|
546
570
|
try {
|
|
@@ -550,7 +574,7 @@ async function handleUnhandled(error)
|
|
|
550
574
|
fs.appendFileSync(process.env.DCP_WORKER_UNHANDLED_REJECTION_LOG,
|
|
551
575
|
`${Date.now()}: ${error.message}\n${error.stack}\n\n`);
|
|
552
576
|
}
|
|
553
|
-
} catch(e) {}
|
|
577
|
+
} catch(e) {} // eslint-disable-line no-empty
|
|
554
578
|
}
|
|
555
579
|
|
|
556
580
|
/** print the slice report via console.log */
|
|
@@ -608,14 +632,14 @@ function sliceReport()
|
|
|
608
632
|
|
|
609
633
|
report += ('Progress:') + '\n';
|
|
610
634
|
worker.workingSandboxes.forEach(sb => {
|
|
611
|
-
const jobName = sb.job
|
|
635
|
+
const jobName = sb.job?.public?.name || `idek (${sb.jobAddress})`;
|
|
612
636
|
let el = Date.now() - sb.sliceStartTime;
|
|
613
637
|
const t = el < 1000000
|
|
614
638
|
? toInterval(el)
|
|
615
639
|
: 'new';
|
|
616
640
|
|
|
617
641
|
el = sb.progressReports && sb.progressReports.last
|
|
618
|
-
? Date.now() - (sb.sliceStartTime + sb.progressReports.last
|
|
642
|
+
? Date.now() - (sb.sliceStartTime + (sb.progressReports.last?.timestamp ?? 0))
|
|
619
643
|
: 0;
|
|
620
644
|
const pct = (typeof sb.progress) === 'number'
|
|
621
645
|
? `${Number(sb.progress).toFixed(0).padStart(2)}%`
|
|
@@ -647,14 +671,14 @@ function handleSigDeath(signalName, signal)
|
|
|
647
671
|
process.off(signalName, handleSigDeath);
|
|
648
672
|
|
|
649
673
|
if (!worker)
|
|
650
|
-
console.
|
|
674
|
+
console.warn(`trapped ${signalName}, signal ${signal}`);
|
|
651
675
|
else
|
|
652
676
|
{
|
|
653
|
-
console.
|
|
677
|
+
console.warn(`trapped ${signalName}, signal ${signal} -- stopping worker`);
|
|
654
678
|
worker.stop(signalName === 'SIGQUIT');
|
|
655
679
|
}
|
|
656
680
|
|
|
657
|
-
setTimeout(() =>
|
|
681
|
+
setTimeout(() => processExit(signal - 128), getCleanupTimeoutMs()).unref();
|
|
658
682
|
}
|
|
659
683
|
|
|
660
684
|
/**
|
|
@@ -674,7 +698,7 @@ function getCleanupTimeoutMs()
|
|
|
674
698
|
cleanupTimeout = defaultCT;
|
|
675
699
|
if (!getCleanupTimeoutMs.warned)
|
|
676
700
|
{
|
|
677
|
-
console.
|
|
701
|
+
console.error(`warning: dcpConfig.worker.cleanupTimeout is not a number (${dcpConfig.worker.cleanupTimeout})`);
|
|
678
702
|
getCleanupTimeoutMs.warned = true;
|
|
679
703
|
}
|
|
680
704
|
}
|
|
@@ -696,7 +720,7 @@ function verifyDefaultConfigIntegrity()
|
|
|
696
720
|
|
|
697
721
|
if (!fs.existsSync(md5sumPath))
|
|
698
722
|
{
|
|
699
|
-
console.
|
|
723
|
+
console.error(chalk.bold.red(` ! warning: ${md5sumPath} not found; cannot verify configuration integrity`));
|
|
700
724
|
require('dcp/utils').sleep(2);
|
|
701
725
|
}
|
|
702
726
|
else
|
|
@@ -718,7 +742,7 @@ function verifyDefaultConfigIntegrity()
|
|
|
718
742
|
console.warn(' - the Windows Registry');
|
|
719
743
|
|
|
720
744
|
if (require('dcp/build').config.build !== 'debug')
|
|
721
|
-
|
|
745
|
+
processExit(1);
|
|
722
746
|
|
|
723
747
|
console.log(chalk.bold.red.inverse("If this wasn't a debug build, the worker would exit now."));
|
|
724
748
|
require('dcp/utils').sleep(2);
|
|
@@ -728,10 +752,18 @@ function verifyDefaultConfigIntegrity()
|
|
|
728
752
|
if (dcpConfig.cookie !== process.env.DCP_CONFIG_COOKIE || !dcpConfig.cookie)
|
|
729
753
|
{
|
|
730
754
|
console.error(' ! DCP Worker default configuration was not loaded; exiting.');
|
|
731
|
-
|
|
755
|
+
processExit(1);
|
|
732
756
|
}
|
|
733
757
|
}
|
|
734
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
|
+
|
|
735
767
|
/**
|
|
736
768
|
* Cast b to boolean such that 'false' becomes false, falsey things become false, and everything else
|
|
737
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
|
|