dcp-worker 3.2.30-3 → 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 CHANGED
@@ -4,7 +4,12 @@
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,6 +21,7 @@ const path = require('path');
16
21
  const crypto = require('crypto');
17
22
  const chalk = require('chalk');
18
23
  const telnetd = require('../lib/remote-console');
24
+ const utils = require('../lib/utils');
19
25
 
20
26
  const configName = process.env.DCP_CONFIG || '../etc/dcp-worker-config';
21
27
  const EXIT_UNHANDLED = 5;
@@ -35,7 +41,9 @@ const replHelpers = {
35
41
  };
36
42
  telnetd.init(replHelpers);
37
43
 
38
- /* 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
+ */
39
47
  process.env.DCP_CONFIG_COOKIE = (Math.random().toString(16)).slice(2) + '-' + process.pid + '-' + Date.now();
40
48
  require('dcp-client').init({ configName }).then(main).catch(handleUnhandled);
41
49
 
@@ -61,7 +69,6 @@ function parseCliArgs()
61
69
  alias: 'd',
62
70
  describe: 'default proportion of CPU,GPU to use when cores not specified',
63
71
  type: 'string',
64
- default: JSON.stringify(dcpConfig.worker.defaultCoreDensity),
65
72
  },
66
73
  verbose: {
67
74
  alias: 'v',
@@ -400,23 +407,10 @@ async function main()
400
407
 
401
408
  function fetchEventHandler(ev)
402
409
  {
403
- var slicesFetched;
404
-
405
410
  if (ev instanceof Error)
406
- {
407
411
  console.error('Error fetching task:', ev);
408
- return;
409
- }
410
-
411
- if (typeof ev === 'number' || typeof ev === 'string') /* <= June 2023 Worker events: remove ~ Sep 2023 /wg */
412
- slicesFetched = ev;
413
412
  else
414
- {
415
- const task = ev;
416
- slicesFetched = task.slices.length;
417
- }
418
-
419
- dcpWorkerOptions.leavePublicGroup = Boolean(slicesFetched > 0);
413
+ dcpWorkerOptions.leavePublicGroup = Boolean(utils.slicesFetched(ev) > 0);
420
414
  }
421
415
  }
422
416
  }
@@ -499,12 +493,13 @@ function processCoresAndDensity (dcpWorkerOptions, cliArgs)
499
493
 
500
494
  const parseArg = (which) => {
501
495
  if (!cliArgs[which])
502
- return false;
503
-
504
- const [cpu, gpu] = cliArgs[which].split(',');
505
- dcpWorkerOptions[which] = { cpu: Number(cpu || defaultTargets[which].cpu),
506
- gpu: Number(gpu || defaultTargets[which].gpu) };
507
- return true;
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
+ }
508
503
  };
509
504
 
510
505
  parseArg('density');
@@ -512,8 +507,8 @@ function processCoresAndDensity (dcpWorkerOptions, cliArgs)
512
507
 
513
508
  if (dcpWorkerOptions.cores)
514
509
  debugging() && console.debug('dcp-worker: cores =', dcpWorkerOptions.cores);
515
- else
516
- debugging() && console.debug('dcp-worker: core density =', dcpWorkerOptions.defaultCoreDensity);
510
+ if (dcpWorkerOptions.density)
511
+ debugging() && console.debug('dcp-worker: core density =', dcpWorkerOptions.density);
517
512
  }
518
513
 
519
514
  /**
@@ -637,14 +632,14 @@ function sliceReport()
637
632
 
638
633
  report += ('Progress:') + '\n';
639
634
  worker.workingSandboxes.forEach(sb => {
640
- const jobName = sb.job && sb.job.public && sb.job.public.name || `idek (${sb.jobAddress})`;
635
+ const jobName = sb.job?.public?.name || `idek (${sb.jobAddress})`;
641
636
  let el = Date.now() - sb.sliceStartTime;
642
637
  const t = el < 1000000
643
638
  ? toInterval(el)
644
639
  : 'new';
645
640
 
646
641
  el = sb.progressReports && sb.progressReports.last
647
- ? Date.now() - (sb.sliceStartTime + sb.progressReports.last.timestamp)
642
+ ? Date.now() - (sb.sliceStartTime + (sb.progressReports.last?.timestamp ?? 0))
648
643
  : 0;
649
644
  const pct = (typeof sb.progress) === 'number'
650
645
  ? `${Number(sb.progress).toFixed(0).padStart(2)}%`
@@ -49,7 +49,7 @@
49
49
  // keystore('~/.dcp/scott'),
50
50
  ],
51
51
 
52
- jobAddresses: [], /* If specified, restrict the worker to only these jobs */
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
- 8edf1c57bee521ed7f151a21b8f3f34d
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
- if (i < this.progressBars.length) {
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.data.length})`);
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
 
@@ -15,6 +15,7 @@ const chalk = require('chalk');
15
15
  const blessed = require('blessed');
16
16
  const contrib = require('blessed-contrib');
17
17
  const components = require('./blessed-components');
18
+ const utils = require('../lib/utils');
18
19
 
19
20
  const { replaceWorkerEvent, replaceSandboxEvent } = require('./default-ui-events');
20
21
 
@@ -52,7 +53,7 @@ exports.init = function dashboard$$init(worker, options)
52
53
 
53
54
  const sandboxPane = grid.set(0, 0, 2, 2, components.sandboxes, {
54
55
  label: 'Sandboxes',
55
- defaultProgressBars: Math.floor(worker.workerOptions.cores.cpu) || 1,
56
+ defaultProgressBars: 0,
56
57
  scrollable: true,
57
58
  alwaysScroll: true,
58
59
  mouse: true,
@@ -99,23 +100,27 @@ exports.init = function dashboard$$init(worker, options)
99
100
 
100
101
  /* Override default event behaviour to work better with the Dashboard. */
101
102
 
102
- replaceSandboxEvent('start', function dashboard$$sliceStart(sandbox, sandboxData, ev) {
103
+ /** XXXpfr @todo Is this correct? Or should we init progressData inside 'slice' like we used to. */
104
+ replaceSandboxEvent('ready', function dashboard$$job(sandbox, sandboxData, ev) {
103
105
  sandboxData.progressData = {
104
106
  indeterminate: true,
105
107
  progress: 0,
106
- label: sandbox.public.name,
108
+ label: sandbox?.public ? sandbox.public.name: '<no-label>',
107
109
  };
108
-
110
+ });
111
+
112
+ replaceSandboxEvent('slice', function dashboard$$slice(sandbox, sandboxData, ev) {
109
113
  sandboxPane.data.push(sandboxData.progressData);
110
114
  sandboxPane.update();
111
115
  });
112
116
 
113
- replaceSandboxEvent('sliceProgress', function dashboard$$sliceProgress(sandbox, sandboxData, ev) {
114
- if (ev.indeterminate)
117
+ replaceSandboxEvent('progress', function dashboard$$progress(sandbox, sandboxData, ev) {
118
+ if (!ev)
115
119
  {
116
120
  sandboxData.progressData.progress = 100;
117
121
  setTimeout(() => {
118
- if (sandboxData.progressData.indeterminate) {
122
+ if (sandboxData.progressData.indeterminate)
123
+ {
119
124
  sandboxData.progressData.progress = 0;
120
125
  sandboxPane.update();
121
126
  }
@@ -123,53 +128,54 @@ exports.init = function dashboard$$init(worker, options)
123
128
  }
124
129
  else
125
130
  {
126
- sandboxData.progressData.progress = ev.progress;
131
+ sandboxData.progressData.progress = ev;
127
132
  sandboxData.progressData.indeterminate = false;
128
133
  }
129
134
 
130
135
  sandboxPane.update();
131
136
  });
132
137
 
133
- replaceSandboxEvent('sliceFinish', function dashboard$$sliceFinish(sandbox, sandboxData, ev) {
138
+ replaceSandboxEvent('sliceEnd', function dashboard$$sliceEnd(sandbox, sandboxData, ev) {
134
139
  sandboxPane.data = sandboxPane.data.filter(d => d != sandboxData.progressData);
140
+ sandboxData.progressData.progress = 0;
135
141
  sandboxPane.update();
136
142
  });
137
143
 
138
- worker.on('payment', updateWorkerInfo);
144
+ replaceSandboxEvent('end', function dashboard$$end(sandbox, sandboxData, ev) {
145
+ sandboxPane.data = sandboxPane.data.filter(d => d != sandboxData.progressData);
146
+ sandboxPane.deleteProgressBar();
147
+ sandboxData.progressData.progress = 0;
148
+ sandboxPane.update();
149
+ });
139
150
 
140
- replaceWorkerEvent('fetchStart', function dashboard$$fetchStart(ev) {
151
+ replaceWorkerEvent('beforeFetch', function dashboard$$beforeFetch(ev) {
141
152
  sliceFetchStatus = SLICE_FETCH_STATUS.FETCHING;
142
153
  updateWorkerInfo();
143
154
  });
144
155
 
145
156
  replaceWorkerEvent('fetch', function dashboard$$fetch(ev) {
146
- var slicesFetched;
147
-
157
+ sliceFetchStatus = SLICE_FETCH_STATUS.NO_WORK;
148
158
  if (ev instanceof Error)
149
- {
150
159
  console.error('Error fetching slices:', ev);
151
- return;
152
- }
153
-
154
- if (typeof ev === 'number' || typeof ev === 'string') /* <= June 2023 Worker events: remove ~ Sep 2023 /wg */
155
- slicesFetched = ev;
156
- else
157
- {
158
- const task = ev;
159
- slicesFetched = task.slices.length;
160
- }
161
-
162
- if (slicesFetched === 0 && sandboxPane.data.length === 0) {
163
- sliceFetchStatus = SLICE_FETCH_STATUS.NO_WORK;
164
- } else {
160
+ else if ( !(utils.slicesFetched(ev) === 0 && sandboxPane.data.length === 0))
165
161
  sliceFetchStatus = SLICE_FETCH_STATUS.WORKING;
166
- }
167
-
168
162
  updateWorkerInfo();
169
163
  });
170
164
 
171
- replaceWorkerEvent('fetchError', function dashabord$$fetchError() {
172
- sliceFetchStatus = SLICE_FETCH_STATUS.NO_WORK;
165
+ worker.on('end', () => { screen.destroy(); });
166
+
167
+ worker.on('sandbox', function dashboard$$sandbox(ev) {
168
+ sandboxPane.createProgressBar();
169
+ sandboxPane.update();
170
+ });
171
+
172
+ worker.on('payment', function dashboard$$payment(ev) {
173
+ const payment = parseFloat(ev);
174
+
175
+ if (!isNaN(payment))
176
+ totalDCCs += payment;
177
+
178
+ sandboxPane.update();
173
179
  updateWorkerInfo();
174
180
  });
175
181
  };
@@ -26,6 +26,8 @@
26
26
  */
27
27
  'use strict';
28
28
 
29
+ const utils = require('../lib/utils');
30
+
29
31
  const sandboxEventHandlers = {};
30
32
  const workerEventHandlers = {};
31
33
 
@@ -50,35 +52,28 @@ exports.hook = function hookWorkerEvents$$hook(worker, options)
50
52
  if (!sandbox.jobAddress)
51
53
  return '<no job>';
52
54
 
53
- const address = sandbox.jobAddress ? sandbox.jobAddress.slice(0, truncationLength) : 'null';
54
- const baseInfo = sandbox.public?.name ? `${address}: ${sandbox.public.name}` : `${address}:`;
55
+ const address = sandbox.jobAddress.slice(0, truncationLength);
56
+ const baseInfo = sandbox?.public ? `${address}: ${sandbox.public.name}` : address;
55
57
 
56
58
  if (!sliceNumber)
57
- sliceNumber = sandbox.slice ? sandbox.slice.sliceNumber : 0;
58
- return sliceNumber ? `slice ${sliceNumber}, ${baseInfo}` : baseInfo;
59
+ sliceNumber = sandbox.sliceNumber;
60
+ return sliceNumber > 0 ? `slice ${sliceNumber}, ${baseInfo}` : baseInfo;
59
61
  }
60
62
 
61
63
  sandboxEventHandlers.ready = function sandboxReadyHandler(sandbox, sandboxData, ev) {
62
64
  console.log(` . Sandbox ${sandboxData.shortId}: Initialized`);
63
65
  };
64
66
 
65
- sandboxEventHandlers.terminated = function sandboxTerminatedHandler(sandbox, sandboxData, ev) {
66
- const sliceInfo = sliceMap[sandbox.id];
67
- console.log(` * Sandbox ${sandboxData.shortId}: Terminated: ${makeSliceId(sandbox, sliceInfo?.slice)}`);
68
- delete sliceMap[sandbox.id];
69
- };
70
-
71
- sandboxEventHandlers.start = function sliceStartHandler(sandbox, sandboxData, ev) {
72
- const sliceNumber = sandbox.slice ? sandbox.slice.sliceNumber : 0;
73
- sliceMap[sandbox.id] = { slice: sliceNumber, t0: Date.now() };
67
+ sandboxEventHandlers.slice = function sliceHandler(sandbox, sandboxData, ev) {
68
+ sliceMap[sandbox.id] = { slice: sandbox.sliceNumber, t0: Date.now() };
74
69
  console.log(` . Sandbox ${sandboxData.shortId}: Slice Started: ${makeSliceId(sandbox)}`);
75
70
  };
76
71
 
77
- sandboxEventHandlers.sliceProgress = function sliceProgressHandler(sandbox, sandbodData, ev) {
78
- // NOP
72
+ sandboxEventHandlers.progress = function progressHandler(sandbox, sandboxdData, ev) {
73
+ // Overridden in dashboard-tui.js
79
74
  };
80
75
 
81
- sandboxEventHandlers.sliceFinish = function sliceFinishHandler(sandbox, sandboxData, ev) {
76
+ sandboxEventHandlers.sliceEnd = function sliceEndHandler(sandbox, sandboxData, ev) {
82
77
  const sliceInfo = sliceMap[sandbox.id];
83
78
  if (sliceInfo)
84
79
  console.log(` * Sandbox ${sandboxData.shortId}: Slice Completed: ${makeSliceId(sandbox, sliceInfo.slice)}: dt ${Date.now() - sliceInfo.t0}ms`);
@@ -86,8 +81,14 @@ exports.hook = function hookWorkerEvents$$hook(worker, options)
86
81
  console.log(` * Sandbox ${sandboxData.shortId}: Slice Completed: ${makeSliceId(sandbox)}`);
87
82
  };
88
83
 
84
+ sandboxEventHandlers.end = function endHandler(sandbox,sandboxData, ev) {
85
+ const sliceInfo = sliceMap[sandbox.id];
86
+ console.log(` * Sandbox ${sandboxData.shortId}: Terminated: ${makeSliceId(sandbox, sliceInfo?.slice)}`);
87
+ delete sliceMap[sandbox.id];
88
+ };
89
+
89
90
  workerEventHandlers.payment = function paymentHandler(ev) {
90
- const payment = parseFloat(ev.payment);
91
+ const payment = parseFloat(ev);
91
92
 
92
93
  if (isNaN(payment))
93
94
  console.error(' ! Failed to parse payment:', payment);
@@ -95,39 +96,23 @@ exports.hook = function hookWorkerEvents$$hook(worker, options)
95
96
  console.log(` . Payment: ${payment.toFixed(3)} ⊇`);
96
97
  };
97
98
 
98
- workerEventHandlers.fetchStart = function fetchStartHandler() {
99
+ workerEventHandlers.beforeFetch = function beforeFetchHandler() {
99
100
  options.verbose && console.log(' * Fetching slices...');
100
101
  };
101
102
 
102
103
  workerEventHandlers.fetch = function fetchHandler(ev) {
103
- var slicesFetched;
104
-
105
104
  if (ev instanceof Error)
106
- {
107
105
  console.error(' ! Failed to fetch slices:', ev);
108
- return;
109
- }
110
-
111
- if (typeof ev === 'number' || typeof ev === 'string') /* <= June 2023 Worker events: remove ~ Sep 2023 /wg */
112
- slicesFetched = ev;
113
106
  else
114
- {
115
- const task = ev;
116
- slicesFetched = task.slices.length;
117
- }
118
-
119
- options.verbose && console.log(' . Fetched', slicesFetched, 'slices');
107
+ options.verbose && console.log(' . Fetched', utils.slicesFetched(ev), 'slices');
120
108
  };
121
109
 
122
- workerEventHandlers.fetchError = function fetchErrorHandler(ev) {
123
- console.log(' ! Failed to fetch slices:', ev);
124
- };
125
110
 
126
- workerEventHandlers.submitStart = function submitStartHandler() {
111
+ workerEventHandlers.beforeResult = function beforeResultHandler() {
127
112
  options.verbose >= 2 && console.log(' * Submitting results...');
128
113
  };
129
114
 
130
- workerEventHandlers.submit = function submitHandler() {
115
+ workerEventHandlers.result = function resultHandler() {
131
116
  options.verbose >= 2 && console.log(' . Submitted');
132
117
  };
133
118
 
@@ -144,14 +129,14 @@ exports.hook = function hookWorkerEvents$$hook(worker, options)
144
129
  * called `sandboxData` which is just arbitrary storage for the eventHandlers' use, eg for memos.
145
130
  */
146
131
  for (let eventName in workerEventHandlers)
147
- worker.addEventListener(eventName, workerEventHandlers[eventName]);
132
+ worker.on(eventName, (...args) => workerEventHandlers[eventName](...args));
148
133
 
149
134
  worker.on('sandbox', function newSandboxHandler(sandbox) {
150
135
  const sandboxData = {
151
136
  shortId: sandbox.id.toString(10).padStart(3)
152
137
  };
153
138
  for (let eventName in sandboxEventHandlers)
154
- sandbox.addEventListener(eventName, (...args) => sandboxEventHandlers[eventName](sandbox, sandboxData, ...args));
139
+ sandbox.on(eventName, (...args) => sandboxEventHandlers[eventName](sandbox, sandboxData, ...args));
155
140
  });
156
141
 
157
142
  exports.sandboxEventHandlers = sandboxEventHandlers;
@@ -36,7 +36,10 @@ function getLogger(options)
36
36
  catch (error)
37
37
  {
38
38
  if (error.code === 'MODULE_NOT_FOUND')
39
- throw new Error(`Unknown outputMode "${options.outputMode}"`);
39
+ {
40
+ const errorMessageStart = error.message.replace(/\n.*/g, '');
41
+ error.message = `Unknown outputMode "${options.outputMode} (${errorMessageStart})`;
42
+ }
40
43
  throw error;
41
44
  }
42
45
  }
@@ -123,5 +126,5 @@ function format(...argv)
123
126
  * Options for util.inspect. Loggers which cannot deal with colours should force this false.
124
127
  */
125
128
  exports.inspectOptions = {
126
- colors: process.stdout.hasColors() || process.env.FORCE_COLOR,
129
+ colors: process.stdout.isTTY && process.stdout.hasColors() || process.env.FORCE_COLOR,
127
130
  };
package/lib/utils.js ADDED
@@ -0,0 +1,28 @@
1
+
2
+ /**
3
+ * @file utils.js
4
+ * Shared library code.
5
+ *
6
+ * @author Paul, paul@distributive.network
7
+ * @date August 2023
8
+ */
9
+ 'use strict';
10
+
11
+ /**
12
+ * Figure out #slices fetched from the different forms of the 'fetch' event.
13
+ * @param {*|string|number} task
14
+ * @returns {number}
15
+ */
16
+ function slicesFetched (task)
17
+ {
18
+ if (typeof task === 'number') /* <= June 2023 Worker events: remove ~ Sep 2023 /wg */
19
+ return task;
20
+ if (typeof task === 'string') /* <= June 2023 Worker events: remove ~ Sep 2023 /wg */
21
+ return parseInt(task) || 0;
22
+ let slicesFetched = 0;
23
+ for (const job in task.slices)
24
+ slicesFetched += task.slices[job];
25
+ return slicesFetched;
26
+ }
27
+
28
+ exports.slicesFetched = slicesFetched;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dcp-worker",
3
- "version": "3.2.30-3",
3
+ "version": "3.2.30-4",
4
4
  "description": "JavaScript portion of DCP Workers for Node.js",
5
5
  "main": "bin/dcp-worker",
6
6
  "keywords": [
@@ -48,6 +48,14 @@
48
48
  "@kingsds/eslint-config": "^1.0.1",
49
49
  "eslint": "7.30.0"
50
50
  },
51
+ "peerDependencies": {
52
+ "node-eventlog": "https://gitpkg.now.sh/Distributive-Network/node-eventlog/package?dcp/0.0.1"
53
+ },
54
+ "peerDependenciesMeta": {
55
+ "node-eventlog": {
56
+ "optional": true
57
+ }
58
+ },
51
59
  "engines": {
52
60
  "node": ">=16",
53
61
  "npm": ">=7"