dcp-worker 3.2.30-9 → 3.2.31
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 +27 -0
- package/bin/dcp-worker +160 -95
- package/bin/publish-docs.sh +74 -0
- package/catalog-info.yaml +21 -0
- package/docs/CODEOWNERS +2 -0
- package/docs/mkdocs.yml +16 -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 +98 -62
- 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 +16 -6
- package/lib/worker-loggers/common-types.js +0 -24
package/lib/startWorkerLogger.js
CHANGED
|
@@ -1,94 +1,130 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file startWorkerLogger.js
|
|
3
|
+
* Start the DCP Worker logging subsystem. Sets console.log (etc) redirection, determine
|
|
4
|
+
* the correct log target (screen, TUI, syslog, windows event log, file) and redirect the
|
|
5
|
+
* output there.
|
|
3
6
|
* @author Ryan Rossiter, ryan@kingsds.network
|
|
4
7
|
* @date April 2020
|
|
8
|
+
* @author Wes Garland, wes@distributive.network
|
|
5
9
|
*/
|
|
10
|
+
'use strict';
|
|
6
11
|
|
|
7
12
|
const process = require('process');
|
|
8
13
|
const os = require('os');
|
|
9
|
-
require('
|
|
14
|
+
const util = require('util');
|
|
10
15
|
|
|
11
16
|
/**
|
|
12
17
|
* Detects and returns the appropriate logger for the environment
|
|
18
|
+
* @param {object} options - cliArgs from worker
|
|
13
19
|
* @returns {WorkerLogger}
|
|
14
20
|
*/
|
|
15
|
-
function getLogger(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
function getLogger(options)
|
|
22
|
+
{
|
|
23
|
+
if (options.outputMode === 'detect')
|
|
24
|
+
{
|
|
25
|
+
options.outputMode = 'console';
|
|
26
|
+
/* have TTY - use dashboard when charset supports line drawing */
|
|
27
|
+
if ((process.env.LANG && process.env.LANG.match(/utf-|latin-|iso-8859-/i)) || os.platform() === 'win32')
|
|
28
|
+
options.outputMode = 'dashboard';
|
|
23
29
|
}
|
|
24
30
|
|
|
25
31
|
try
|
|
26
32
|
{
|
|
27
|
-
const om = require('path').basename(outputMode);
|
|
33
|
+
const om = require('path').basename(options.outputMode);
|
|
28
34
|
return require('./worker-loggers/' + om);
|
|
29
35
|
}
|
|
30
36
|
catch (error)
|
|
31
37
|
{
|
|
32
|
-
|
|
33
|
-
|
|
38
|
+
if (error.code === 'MODULE_NOT_FOUND')
|
|
39
|
+
{
|
|
40
|
+
const errorMessageStart = error.message.replace(/\n.*/g, '');
|
|
41
|
+
error.message = `Unknown outputMode "${options.outputMode} (${errorMessageStart})`;
|
|
42
|
+
}
|
|
43
|
+
throw error;
|
|
34
44
|
}
|
|
35
45
|
}
|
|
36
46
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
sliceFinish: 'sandbox$onSliceFinish',
|
|
52
|
-
terminated: 'sandbox$onWorkerStop',
|
|
53
|
-
}
|
|
47
|
+
/**
|
|
48
|
+
* Start intercepting console.* methods so that log output from the worker goes to the appropriate log
|
|
49
|
+
* target; eg syslog, file, windows event log, etc. Unlike the telnet console log interceptor which is
|
|
50
|
+
* merely a passthrough shim, this is a "dead end" interceptor - we do not pass the log message through
|
|
51
|
+
* to the original console method. This implies, for example, that sending console messages to syslogd
|
|
52
|
+
* quiesces the tty output.
|
|
53
|
+
*
|
|
54
|
+
* @param {object} options - cliArgs from worker
|
|
55
|
+
*/
|
|
56
|
+
exports.init = function startWorkerLogger$$init(options)
|
|
57
|
+
{
|
|
58
|
+
const logger = getLogger(options);
|
|
59
|
+
|
|
60
|
+
logger.init(options);
|
|
54
61
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
62
|
+
/* The logger module's exports are its API. The following functions are supported, in this order
|
|
63
|
+
* of severity:
|
|
64
|
+
* . debug: debug-level message
|
|
65
|
+
* . info: informational message
|
|
66
|
+
* . log: normal, but significant, condition
|
|
67
|
+
* . warn: warning conditions
|
|
68
|
+
* . error: error conditions
|
|
69
|
+
*
|
|
70
|
+
* Additionally, generic functions may be used when one of the above is not defined:
|
|
71
|
+
* . at: write a log message at a specific log level; the level is the first argument
|
|
72
|
+
* . raw: same as at, but arguments are not formatted
|
|
73
|
+
* . any: write a log message without regard to log level
|
|
74
|
+
*
|
|
75
|
+
* All of these functions, with the exception of raw, receive only string arguments.
|
|
65
76
|
*/
|
|
66
|
-
startWorkerLogger(worker, options={}) {
|
|
67
|
-
const logger = getLogger(options);
|
|
68
|
-
logger.init(worker, options);
|
|
69
77
|
|
|
70
|
-
|
|
78
|
+
for (let level of ['debug', 'error', 'info', 'log', 'warn'])
|
|
79
|
+
{
|
|
80
|
+
if (logger[level])
|
|
81
|
+
console[level] = (...args) => logger[level]( ...format(...args));
|
|
82
|
+
else if (logger.at)
|
|
83
|
+
console[level] = (...args) => logger.at(level, ...format(...args));
|
|
84
|
+
else if (logger.raw)
|
|
85
|
+
console[level] = (...args) => logger.raw(level, ...args);
|
|
86
|
+
else if (logger.any)
|
|
87
|
+
console[level] = (...args) => logger.any(`${level}:`, format(...args));
|
|
88
|
+
else
|
|
71
89
|
{
|
|
72
|
-
|
|
73
|
-
|
|
90
|
+
require('./remote-console').reintercept();
|
|
91
|
+
throw new Error('logger module missing export for ' + level);
|
|
74
92
|
}
|
|
75
|
-
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
require('./remote-console').reintercept();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Format console.log arguments for use by a non-native logger, eg syslog. All non-string arguments are
|
|
100
|
+
* converted into the best human-readable strings we can muster.
|
|
101
|
+
*/
|
|
102
|
+
function format(...argv)
|
|
103
|
+
{
|
|
104
|
+
for (let i in argv)
|
|
105
|
+
{
|
|
106
|
+
try
|
|
76
107
|
{
|
|
77
|
-
if (typeof
|
|
78
|
-
|
|
108
|
+
if (typeof argv[i] === 'object' && argv[i] instanceof String)
|
|
109
|
+
argv[i] = String(argv[i]);
|
|
110
|
+
if (typeof argv[i] === 'object')
|
|
111
|
+
argv[i] = util.inspect(argv[i], exports.inspectOptions);
|
|
112
|
+
if (typeof argv[i] !== 'string')
|
|
113
|
+
argv[i] = String(argv[i]);
|
|
114
|
+
}
|
|
115
|
+
catch(e)
|
|
116
|
+
{
|
|
117
|
+
if (e instanceof TypeError)
|
|
118
|
+
argv[i] = '[encoding error: ' + e.message + ']';
|
|
79
119
|
}
|
|
80
|
-
|
|
81
|
-
worker.on('sandbox', (sandbox) => {
|
|
82
|
-
/**
|
|
83
|
-
* logger.onSandboxStart can return a data object that will be provided to
|
|
84
|
-
* the other sandbox event handlers
|
|
85
|
-
*/
|
|
86
|
-
const data = logger.onSandboxReady(sandbox) || {};
|
|
87
|
-
for (const [ev, handler] of Object.entries(sandboxEvents))
|
|
88
|
-
{
|
|
89
|
-
if (typeof logger[handler] === 'function')
|
|
90
|
-
sandbox.on(ev, logger[handler].bind(logger, sandbox, data));
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
120
|
}
|
|
94
|
-
|
|
121
|
+
|
|
122
|
+
return argv;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Options for util.inspect. Loggers which cannot deal with colours should force this false.
|
|
127
|
+
*/
|
|
128
|
+
exports.inspectOptions = {
|
|
129
|
+
colors: process.stdout.isTTY && process.stdout.hasColors() || process.env.FORCE_COLOR,
|
|
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;
|
|
@@ -1,114 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* This worker logger uses console.log to produce
|
|
7
|
-
* simple log output.
|
|
2
|
+
* @file worker-loggers/console.js
|
|
3
|
+
* Logger interface which just logs to the node console on stdout/stderr.
|
|
4
|
+
* @author Wes Garland, wes@distributive.network
|
|
5
|
+
* @date June 2023
|
|
8
6
|
*/
|
|
7
|
+
'use strict';
|
|
9
8
|
|
|
10
|
-
require('
|
|
9
|
+
const process = require('process');
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
* Sandbox 1: Slice Completed: slice 1, 0x5b5214D48F0428669c4E: Simple Job: dt 114ms
|
|
16
|
-
* When this.enhancedDisplay is false
|
|
17
|
-
* Sandbox 1: Slice Started: 0x5b5214D48F0428669c4E68779896D29D77c42903 Simple Job
|
|
18
|
-
* Sandbox 1: Slice Completed: 0x5b5214D48F0428669c4E68779896D29D77c42903 Simple Job
|
|
19
|
-
* @type {WorkerLogger}
|
|
20
|
-
*/
|
|
21
|
-
const consoleLogger = {
|
|
22
|
-
init(worker, options) {
|
|
23
|
-
this.worker = worker;
|
|
24
|
-
this.options = Object.assign({}, options);
|
|
25
|
-
this.sliceMap = {}; // jobAddress --> ( sliceNumber, t0 )
|
|
26
|
-
this.enhancedDisplay = true; // When false, no timing, no sliceNumber, full jobAddress
|
|
27
|
-
this.truncationLength = 22; // Extra 2 for '0x'
|
|
28
|
-
},
|
|
29
|
-
|
|
30
|
-
id (sandbox, sliceNumber) {
|
|
31
|
-
if (!this.enhancedDisplay)
|
|
32
|
-
return sandbox.public ? `${sandbox.jobAddress} ${sandbox.public.name}` : `${sandbox.jobAddress}`;
|
|
33
|
-
|
|
34
|
-
const address = sandbox.jobAddress ? sandbox.jobAddress.slice(0, this.truncationLength) : 'null';
|
|
35
|
-
const baseInfo = sandbox.public ? `${address}: ${sandbox.public.name}` : `${address}:`;
|
|
36
|
-
|
|
37
|
-
if (!sliceNumber)
|
|
38
|
-
sliceNumber = sandbox.slice ? sandbox.slice.sliceNumber : 0;
|
|
39
|
-
return sliceNumber ? `slice ${sliceNumber}, ${baseInfo}` : baseInfo;
|
|
40
|
-
},
|
|
41
|
-
|
|
42
|
-
onSandboxReady(sandbox) {
|
|
43
|
-
const shortId = sandbox.id.toString(10).padStart(3);
|
|
11
|
+
exports.init = function console$$init(options)
|
|
12
|
+
{
|
|
13
|
+
const myConsole = new (require('console').Console)(process);
|
|
44
14
|
|
|
45
|
-
|
|
46
|
-
|
|
15
|
+
delete exports.init; // singleton
|
|
16
|
+
if (process.env.RAW_CONSOLE)
|
|
17
|
+
{
|
|
18
|
+
/* raw mode is used to debug node-inspect problems by dumping raw types directly to console.log */
|
|
19
|
+
exports.raw = function console$$raw(level, ...args) {
|
|
20
|
+
myConsole[level](...args);
|
|
47
21
|
};
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
console.log(` * Sandbox ${sandboxData.shortId}: Slice Started: ${this.id(sandbox)}`);
|
|
58
|
-
},
|
|
59
|
-
|
|
60
|
-
sandbox$onSliceProgress(sandbox, sandboxData, ev) {
|
|
61
|
-
// something
|
|
62
|
-
},
|
|
63
|
-
|
|
64
|
-
sandbox$onSliceFinish(sandbox, sandboxData, ev) {
|
|
65
|
-
const sliceInfo = this.sliceMap[sandbox.id];
|
|
66
|
-
if (sliceInfo && this.enhancedDisplay)
|
|
67
|
-
console.log(` * Sandbox ${sandboxData.shortId}: Slice Completed: ${this.id(sandbox, sliceInfo.slice)}: dt ${Date.now() - sliceInfo.t0}ms`);
|
|
68
|
-
else
|
|
69
|
-
console.log(` * Sandbox ${sandboxData.shortId}: Slice Completed: ${this.id(sandbox)}`);
|
|
70
|
-
},
|
|
71
|
-
|
|
72
|
-
sandbox$onWorkerStop(sandbox, sandboxData, ev) {
|
|
73
|
-
const sliceInfo = this.sliceMap[sandbox.id];
|
|
74
|
-
delete this.sliceMap[sandbox.id];
|
|
75
|
-
console.log(` * Sandbox ${sandboxData.shortId}: Terminated: ${this.id(sandbox, sliceInfo?.slice)}`);
|
|
76
|
-
},
|
|
77
|
-
|
|
78
|
-
onPayment({ payment }) {
|
|
79
|
-
try {
|
|
80
|
-
payment = parseFloat(payment);
|
|
81
|
-
} catch (e) {
|
|
82
|
-
console.error(" ! Failed to parse payment:", payment);
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (payment > 0) console.log(` * DCC Credit: ${payment.toFixed(3)}`);
|
|
87
|
-
},
|
|
88
|
-
|
|
89
|
-
onFetchingSlices() {
|
|
90
|
-
this.options.verbose && console.log(" * Fetching slices...");
|
|
91
|
-
},
|
|
92
|
-
|
|
93
|
-
onFetchedSlices(ev) {
|
|
94
|
-
this.options.verbose && console.log(" * Fetched", ev);
|
|
95
|
-
},
|
|
96
|
-
|
|
97
|
-
onFetchSlicesFailed(ev) {
|
|
98
|
-
console.log(" ! Failed to fetch slices:", ev);
|
|
99
|
-
},
|
|
100
|
-
|
|
101
|
-
onSubmitStart() {
|
|
102
|
-
this.options.verbose >= 2 && console.log(" * Submitting results...");
|
|
103
|
-
},
|
|
104
|
-
|
|
105
|
-
onSubmit() {
|
|
106
|
-
this.options.verbose >= 2 && console.log(" * Submitted");
|
|
107
|
-
},
|
|
108
|
-
|
|
109
|
-
onSubmitError(ev) {
|
|
110
|
-
console.log(" ! Failed to submit results:", ev);
|
|
111
|
-
},
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
Object.assign(exports, consoleLogger);
|
|
22
|
+
}
|
|
23
|
+
else
|
|
24
|
+
{
|
|
25
|
+
/* Log a single string to the console; conceptually very similar to other loggers */
|
|
26
|
+
exports.at = function console$$at(level, ...args) {
|
|
27
|
+
myConsole[level](args.join(' '));
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -6,183 +6,43 @@
|
|
|
6
6
|
* This worker logger uses the blessed library to create
|
|
7
7
|
* a monitoring dashboard for the worker.
|
|
8
8
|
*/
|
|
9
|
+
'use strict';
|
|
9
10
|
|
|
10
|
-
const dcpConfig = require('dcp/dcp-config');
|
|
11
|
-
const blessed = require('blessed');
|
|
12
|
-
const contrib = require('blessed-contrib');
|
|
13
11
|
const chalk = require('chalk');
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
this.worker = worker;
|
|
30
|
-
this.options = options;
|
|
31
|
-
this.totalDCCs = 0;
|
|
32
|
-
this.sliceFetchStatus = SLICE_FETCH_STATUS.IDLE;
|
|
33
|
-
exports.screen = this.screen = blessed.screen();
|
|
34
|
-
const grid = new contrib.grid({rows: 3, cols: 5, screen: this.screen});
|
|
35
|
-
|
|
36
|
-
const log = grid.set(0, 2, 2, 3, components.log, {
|
|
37
|
-
label: 'Worker Log',
|
|
38
|
-
scrollable: true,
|
|
39
|
-
alwaysScroll: true,
|
|
40
|
-
mouse: true,
|
|
41
|
-
scrollbar: {
|
|
42
|
-
bg: 'blue',
|
|
43
|
-
},
|
|
44
|
-
});
|
|
12
|
+
const _console = new (require('console').Console)(process);
|
|
13
|
+
|
|
14
|
+
exports.init = function dashboardLogger$$init(options)
|
|
15
|
+
{
|
|
16
|
+
function logWrapperFactory(logLevel)
|
|
17
|
+
{
|
|
18
|
+
const inspect = Symbol.for('nodejs.util.inspect.custom');
|
|
19
|
+
const dashboardTui = require('../dashboard-tui');
|
|
20
|
+
|
|
21
|
+
return function wrappedLogFun() {
|
|
22
|
+
if (!dashboardTui.logPane) /* no logPane => TUI not ready - fallback to console */
|
|
23
|
+
{
|
|
24
|
+
const consoleLogger = require('./console');
|
|
25
|
+
if (consoleLogger.init)
|
|
26
|
+
consoleLogger.init();
|
|
45
27
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
28
|
+
const logAt = consoleLogger.at || consoleLogger.raw;
|
|
29
|
+
logAt(logLevel, ...arguments);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const argv = Array.from(arguments);
|
|
34
|
+
for (let i in argv)
|
|
49
35
|
{
|
|
50
|
-
if (
|
|
51
|
-
|
|
36
|
+
if (argv[i] instanceof Error || (typeof argv[i] === 'object' && argv[i][inspect]))
|
|
37
|
+
argv[i] = util.inspect(argv[i]);
|
|
38
|
+
else if (logLevel === 'error' && typeof argv[i] === 'string')
|
|
39
|
+
argv[i] = chalk.red(argv[i]);
|
|
52
40
|
}
|
|
53
|
-
|
|
41
|
+
dashboardTui.logPane.log(...argv);
|
|
54
42
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
this.sandboxes = grid.set(0, 0, 2, 2, components.sandboxes, {
|
|
58
|
-
label: 'Sandboxes',
|
|
59
|
-
defaultProgressBars: this.worker.cpuCores,
|
|
60
|
-
scrollable: true,
|
|
61
|
-
alwaysScroll: true,
|
|
62
|
-
mouse: true,
|
|
63
|
-
scrollbar: {
|
|
64
|
-
bg: 'blue',
|
|
65
|
-
},
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
this.workerInfo = grid.set(2, 0, 1, 5, blessed.text);
|
|
69
|
-
this.updateWorkerInfo();
|
|
70
|
-
|
|
71
|
-
setInterval(() => this.screen.render(), 50).unref(); /* 50ms = 20 fps */
|
|
72
|
-
|
|
73
|
-
function raise(sig)
|
|
74
|
-
{
|
|
75
|
-
process.kill(process.pid, sig);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/* Apply key bindings which mimic canonical input mode */
|
|
79
|
-
this.screen.key(['C-c'], () => raise('SIGINT'));
|
|
80
|
-
this.screen.key(['C-z'], () => raise('SIGTSTP'));
|
|
81
|
-
this.screen.key(['\u001c'], () => raise('SIGQUIT')); /* C-\ */
|
|
82
|
-
|
|
83
|
-
this.screen.key(['escape'], () => {
|
|
84
|
-
console.log('Stopping worker...');
|
|
85
|
-
worker.stop();
|
|
86
|
-
});
|
|
87
|
-
},
|
|
88
|
-
|
|
89
|
-
updateWorkerInfo() {
|
|
90
|
-
const workerOptions = dcpConfig.worker;
|
|
91
|
-
|
|
92
|
-
this.workerInfo.setLabel(`Worker Status [${this.sliceFetchStatus}]`);
|
|
93
|
-
this.workerInfo.setContent([
|
|
94
|
-
chalk.green(` DCCs Earned: ${chalk.bold(this.totalDCCs.toFixed(7))}`),
|
|
95
|
-
'',
|
|
96
|
-
` Scheduler: ${chalk.yellow(dcpConfig.scheduler.location.href)}`,
|
|
97
|
-
` Bank: ${chalk.yellow(dcpConfig.bank.location.href)}`,
|
|
98
|
-
`Bank Account: ${chalk.yellow(this.worker.paymentAddress || 'Starting...')}`,
|
|
99
|
-
` Identity: ${chalk.yellow(this.worker.identityKeystore? this.worker.identityKeystore.address : 'Starting...')}`,
|
|
100
|
-
` Jobs: ${workerOptions.jobAddresses?.length ? workerOptions.jobAddresses.join(', ') : '<any>'}`,
|
|
101
|
-
` Priv Groups: ${Object.keys(workerOptions.computeGroups).length}`,
|
|
102
|
-
` Pub Group: ${workerOptions.leavePublicGroup ? 'no' : 'yes'}`,
|
|
103
|
-
].join('\n'));
|
|
104
|
-
},
|
|
105
|
-
|
|
106
|
-
onSandboxReady(sandbox) {
|
|
107
|
-
|
|
108
|
-
},
|
|
43
|
+
}
|
|
109
44
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
progress: 0,
|
|
114
|
-
label: sandbox.public.name,
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
this.sandboxes.data.push(sandboxData.progressData);
|
|
118
|
-
|
|
119
|
-
this.sandboxes.update();
|
|
120
|
-
},
|
|
121
|
-
|
|
122
|
-
sandbox$onSliceProgress(sandbox, sandboxData, ev) {
|
|
123
|
-
if (ev.indeterminate) {
|
|
124
|
-
sandboxData.progressData.progress = 100;
|
|
125
|
-
|
|
126
|
-
setTimeout(() => {
|
|
127
|
-
if (sandboxData.progressData.indeterminate) {
|
|
128
|
-
sandboxData.progressData.progress = 0;
|
|
129
|
-
this.sandboxes.update();
|
|
130
|
-
}
|
|
131
|
-
}, 500).unref();
|
|
132
|
-
} else {
|
|
133
|
-
sandboxData.progressData.progress = ev.progress;
|
|
134
|
-
sandboxData.progressData.indeterminate = false;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
this.sandboxes.update();
|
|
138
|
-
},
|
|
139
|
-
|
|
140
|
-
sandbox$onSliceFinish(sandbox, sandboxData, ev) {
|
|
141
|
-
this.sandboxes.data =
|
|
142
|
-
this.sandboxes.data.filter(d => d != sandboxData.progressData);
|
|
143
|
-
|
|
144
|
-
this.sandboxes.update();
|
|
145
|
-
},
|
|
146
|
-
|
|
147
|
-
sandbox$onWorkerStop(sandbox, sandboxData, ev) {
|
|
148
|
-
this.sandbox$onSliceFinish(sandbox, sandboxData, ev);
|
|
149
|
-
},
|
|
150
|
-
|
|
151
|
-
onPayment({ payment }) {
|
|
152
|
-
try {
|
|
153
|
-
payment = parseFloat(payment);
|
|
154
|
-
} catch (e) {
|
|
155
|
-
console.error("Failed to parse payment float:", payment);
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
try {
|
|
160
|
-
this.totalDCCs += payment;
|
|
161
|
-
this.updateWorkerInfo();
|
|
162
|
-
} catch(e) {
|
|
163
|
-
console.error(e.message);
|
|
164
|
-
}
|
|
165
|
-
},
|
|
166
|
-
|
|
167
|
-
onFetchingSlices() {
|
|
168
|
-
this.sliceFetchStatus = SLICE_FETCH_STATUS.FETCHING;
|
|
169
|
-
this.updateWorkerInfo();
|
|
170
|
-
},
|
|
171
|
-
|
|
172
|
-
onFetchedSlices(fetchedSliceCount) {
|
|
173
|
-
if (fetchedSliceCount === 0 && this.sandboxes.data.length === 0) {
|
|
174
|
-
this.sliceFetchStatus = SLICE_FETCH_STATUS.NO_WORK;
|
|
175
|
-
} else {
|
|
176
|
-
this.sliceFetchStatus = SLICE_FETCH_STATUS.WORKING;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
this.updateWorkerInfo();
|
|
180
|
-
},
|
|
181
|
-
|
|
182
|
-
onFetchSlicesFailed(ev) {
|
|
183
|
-
this.sliceFetchStatus = SLICE_FETCH_STATUS.NO_WORK;
|
|
184
|
-
this.updateWorkerInfo();
|
|
185
|
-
},
|
|
186
|
-
};
|
|
45
|
+
for (let level of ['log', 'warn', 'debug', 'info', 'error'])
|
|
46
|
+
exports[level] = logWrapperFactory(level);
|
|
47
|
+
}
|
|
187
48
|
|
|
188
|
-
Object.assign(exports, dashboardLogger);
|