@nosana/node 1.1.45 → 1.1.47-rc
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/dist/package.json +1 -1
- package/dist/src/NodeManager/checkForMaintenance.d.ts +1 -1
- package/dist/src/NodeManager/checkForMaintenance.js +2 -2
- package/dist/src/NodeManager/index.d.ts +5 -0
- package/dist/src/NodeManager/index.js +10 -3
- package/dist/src/cli/commands/start/action.js +9 -1
- package/dist/src/exitCodes.d.ts +11 -0
- package/dist/src/exitCodes.js +11 -0
- package/dist/src/version/index.d.ts +2 -1
- package/dist/src/version/index.js +8 -6
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function checkForMaintenance(): Promise<void>;
|
|
1
|
+
export declare function checkForMaintenance(inJobLoop?: boolean): Promise<void>;
|
|
@@ -18,7 +18,7 @@ function displayUpcomingMaintenanceNotice(status) {
|
|
|
18
18
|
}
|
|
19
19
|
console.log("");
|
|
20
20
|
}
|
|
21
|
-
export async function checkForMaintenance() {
|
|
21
|
+
export async function checkForMaintenance(inJobLoop = false) {
|
|
22
22
|
const status = await getMaintenanceStatus();
|
|
23
23
|
if (!status?.maintenance) {
|
|
24
24
|
if (status?.startsAt || status?.expectedEndAt || status?.reason) {
|
|
@@ -34,7 +34,7 @@ export async function checkForMaintenance() {
|
|
|
34
34
|
cleared = true;
|
|
35
35
|
});
|
|
36
36
|
while (!cleared) {
|
|
37
|
-
await validateCLIVersion();
|
|
37
|
+
await validateCLIVersion(inJobLoop);
|
|
38
38
|
await Promise.race([sleep(NPM_POLL_INTERVAL_S), maintenanceFinished]);
|
|
39
39
|
}
|
|
40
40
|
}
|
|
@@ -2,6 +2,11 @@ export default class NodeManager {
|
|
|
2
2
|
private node;
|
|
3
3
|
private apiHandler;
|
|
4
4
|
private exiting;
|
|
5
|
+
private apiStarted;
|
|
6
|
+
/**
|
|
7
|
+
* Seeded from the environment so the loop survives the process being
|
|
8
|
+
* replaced by an update.
|
|
9
|
+
*/
|
|
5
10
|
inJobLoop: boolean;
|
|
6
11
|
constructor(options: {
|
|
7
12
|
[key: string]: any;
|
|
@@ -12,10 +12,16 @@ import { ping } from './monitoring/ping/PingHandler.js';
|
|
|
12
12
|
import { LogMonitoringRegistry } from './monitoring/LogMonitoringRegistry.js';
|
|
13
13
|
import { checkWSLStatus } from './utils/wslCheck.js';
|
|
14
14
|
import { HostManager } from './node/market/hostManager.js';
|
|
15
|
+
import { IN_JOB_LOOP_ENV } from '../exitCodes.js';
|
|
15
16
|
export default class NodeManager {
|
|
16
17
|
constructor(options) {
|
|
17
18
|
this.exiting = false;
|
|
18
|
-
this.
|
|
19
|
+
this.apiStarted = false;
|
|
20
|
+
/**
|
|
21
|
+
* Seeded from the environment so the loop survives the process being
|
|
22
|
+
* replaced by an update.
|
|
23
|
+
*/
|
|
24
|
+
this.inJobLoop = process.env[IN_JOB_LOOP_ENV] === 'true';
|
|
19
25
|
this.node = createLoggingProxy(new BasicNode(options));
|
|
20
26
|
/**
|
|
21
27
|
* the node class makes the api but we pass the api to the NodeManager class
|
|
@@ -62,7 +68,7 @@ export default class NodeManager {
|
|
|
62
68
|
* start the api of the node and register all the routes of the nodes,
|
|
63
69
|
* we call this here in the init so the api survives restarts between jobs
|
|
64
70
|
*/
|
|
65
|
-
if (!this.
|
|
71
|
+
if (!this.apiStarted) {
|
|
66
72
|
await this.apiHandler.preventMultipleApiStarts();
|
|
67
73
|
await this.apiHandler.start();
|
|
68
74
|
/**
|
|
@@ -71,12 +77,13 @@ export default class NodeManager {
|
|
|
71
77
|
* make a call to the backend per interval to show live ness to the backend
|
|
72
78
|
*/
|
|
73
79
|
await ping();
|
|
80
|
+
this.apiStarted = true;
|
|
74
81
|
}
|
|
75
82
|
}
|
|
76
83
|
async start(marketArg) {
|
|
77
84
|
this.exiting = false;
|
|
78
85
|
if (this.inJobLoop) {
|
|
79
|
-
await Promise.all([validateCLIVersion(), checkForMaintenance()]);
|
|
86
|
+
await Promise.all([validateCLIVersion(true), checkForMaintenance(true)]);
|
|
80
87
|
}
|
|
81
88
|
/**
|
|
82
89
|
* maintenance
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import 'rpc-websockets/dist/lib/client.js';
|
|
2
2
|
import NodeManager from '../../../NodeManager/index.js';
|
|
3
|
+
import { EXIT_CODES } from '../../../exitCodes.js';
|
|
4
|
+
import { validateCLIVersion } from '../../../version/index.js';
|
|
5
|
+
/** Failures no restart resolves: the node reports them and stops. */
|
|
6
|
+
const TERMINAL_ERRORS = ['NodeBannedError', 'NodeNotQualifiedError'];
|
|
3
7
|
export async function startNode(market, options) {
|
|
4
8
|
options.provider = process.argv.some(arg => arg === '--docker') ? 'docker' : 'podman';
|
|
5
9
|
const nodeManager = new NodeManager(options);
|
|
@@ -28,6 +32,8 @@ export async function startNode(market, options) {
|
|
|
28
32
|
console.error('Get support in our Discord Server. Join:');
|
|
29
33
|
console.error('https://nosana.com/discord');
|
|
30
34
|
console.error('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
|
|
35
|
+
// Terminal, and exits without stopping the node: the market position and
|
|
36
|
+
// run belong to the node holding this key.
|
|
31
37
|
if (error.name == 'NodeAlreadyActiveError') {
|
|
32
38
|
process.exit();
|
|
33
39
|
}
|
|
@@ -37,12 +43,14 @@ export async function startNode(market, options) {
|
|
|
37
43
|
}
|
|
38
44
|
catch (error) { }
|
|
39
45
|
await nodeManager.delay(60);
|
|
46
|
+
// Checked here too, as `start()` is out of reach when `init()` fails.
|
|
47
|
+
await validateCLIVersion(true);
|
|
40
48
|
continue;
|
|
41
49
|
}
|
|
42
50
|
else {
|
|
43
51
|
await nodeManager.error();
|
|
44
52
|
await nodeManager.stop();
|
|
45
|
-
process.exit();
|
|
53
|
+
process.exit(TERMINAL_ERRORS.includes(error.name) ? 0 : EXIT_CODES.RESTART);
|
|
46
54
|
}
|
|
47
55
|
}
|
|
48
56
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exit codes the auto-update wrapper acts on; it stops on any other code.
|
|
3
|
+
* Keep in sync with `auto-update/src/index.ts`.
|
|
4
|
+
*/
|
|
5
|
+
export declare const EXIT_CODES: {
|
|
6
|
+
readonly UPDATE: 129;
|
|
7
|
+
readonly UPDATE_IN_JOB_LOOP: 76;
|
|
8
|
+
readonly RESTART: 75;
|
|
9
|
+
};
|
|
10
|
+
/** Set by the wrapper on the process that replaces a node in the job loop. */
|
|
11
|
+
export declare const IN_JOB_LOOP_ENV = "NOSANA_NODE_IN_JOB_LOOP";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exit codes the auto-update wrapper acts on; it stops on any other code.
|
|
3
|
+
* Keep in sync with `auto-update/src/index.ts`.
|
|
4
|
+
*/
|
|
5
|
+
export const EXIT_CODES = {
|
|
6
|
+
UPDATE: 129,
|
|
7
|
+
UPDATE_IN_JOB_LOOP: 76,
|
|
8
|
+
RESTART: 75,
|
|
9
|
+
};
|
|
10
|
+
/** Set by the wrapper on the process that replaces a node in the job loop. */
|
|
11
|
+
export const IN_JOB_LOOP_ENV = 'NOSANA_NODE_IN_JOB_LOOP';
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
/** @param inJobLoop the process that replaces this one stays in the job loop. */
|
|
2
|
+
export declare function validateCLIVersion(inJobLoop?: boolean): Promise<void>;
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { pkg } from '../static/index.js';
|
|
3
|
+
import { EXIT_CODES } from '../exitCodes.js';
|
|
3
4
|
function requiresNewVersion(required, current) {
|
|
4
5
|
return parseInt(required) > parseInt(current);
|
|
5
6
|
}
|
|
6
|
-
function exitCleanly(currentVersion, latestVersion) {
|
|
7
|
+
function exitCleanly(currentVersion, latestVersion, inJobLoop) {
|
|
7
8
|
console.log(chalk.red(`You are currently running Nosana CLI version ${currentVersion}. Version ${latestVersion} has been released, please update your CLI to the latest version using npm install ${pkg.name}.`));
|
|
8
|
-
process.exit(
|
|
9
|
+
process.exit(inJobLoop ? EXIT_CODES.UPDATE_IN_JOB_LOOP : EXIT_CODES.UPDATE);
|
|
9
10
|
}
|
|
10
|
-
|
|
11
|
+
/** @param inJobLoop the process that replaces this one stays in the job loop. */
|
|
12
|
+
export async function validateCLIVersion(inJobLoop = false) {
|
|
11
13
|
try {
|
|
12
14
|
const [current_major, current_minor, current_patch] = pkg.version.split('.');
|
|
13
15
|
if (parseInt(current_major) === 0 &&
|
|
@@ -27,18 +29,18 @@ export async function validateCLIVersion() {
|
|
|
27
29
|
if (parseInt(required_major) === parseInt(current_major)) {
|
|
28
30
|
if (parseInt(required_minor) === parseInt(current_minor)) {
|
|
29
31
|
if (requiresNewVersion(required_patch, current_patch)) {
|
|
30
|
-
exitCleanly(pkg.version, registryLatestVersion);
|
|
32
|
+
exitCleanly(pkg.version, registryLatestVersion, inJobLoop);
|
|
31
33
|
}
|
|
32
34
|
}
|
|
33
35
|
else {
|
|
34
36
|
if (requiresNewVersion(required_minor, current_minor)) {
|
|
35
|
-
exitCleanly(pkg.version, registryLatestVersion);
|
|
37
|
+
exitCleanly(pkg.version, registryLatestVersion, inJobLoop);
|
|
36
38
|
}
|
|
37
39
|
}
|
|
38
40
|
}
|
|
39
41
|
else {
|
|
40
42
|
if (requiresNewVersion(required_major, current_major)) {
|
|
41
|
-
exitCleanly(pkg.version, registryLatestVersion);
|
|
43
|
+
exitCleanly(pkg.version, registryLatestVersion, inJobLoop);
|
|
42
44
|
}
|
|
43
45
|
}
|
|
44
46
|
}
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nosana/node",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.47-rc",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@nosana/node",
|
|
9
|
-
"version": "1.1.
|
|
9
|
+
"version": "1.1.47-rc",
|
|
10
10
|
"license": "ISC",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@coral-xyz/anchor": "^0.28.1-beta.1",
|