@otto-code/brain 0.8.18 → 0.9.0
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/runtime/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type { Runtime } from "../types.js";
|
|
|
3
3
|
import { type InstallProgress, type RuntimeTarget } from "./managed.js";
|
|
4
4
|
export { BACKENDS_DIR, LMSTUDIO_ROOT, listRuntimes as listLmStudioRuntimes } from "./lmstudio.js";
|
|
5
5
|
export { buildArgs, buildEnv, formatCommand, type ServeTarget } from "./args.js";
|
|
6
|
+
export { llamaCppRuntimeDriver, type ModelServerDriverLaunchInput, type ModelServerLaunch, type ModelServerRuntimeDriver, } from "./model-server-driver.js";
|
|
6
7
|
export { installManagedRuntime, removeManagedRuntime, listManagedRuntimes, listRuntimeDevices, verifyRuntimeExecutable, defaultRuntimeSpec, extractArchive, resolveRuntimeVariant, serverExeName, supportedVariants, DEFAULT_LLAMA_BUILD, listRuntimeReleases, latestRuntimeBuild, resolveLatestBuildOrPin, MissingAssetError, type ResolvedBuild, type RuntimeRelease, type RuntimeSpec, type RuntimeTarget, type RuntimeVariant, type InstallProgress, } from "./managed.js";
|
|
7
8
|
/** Every runtime available on this machine, managed first then LM Studio. */
|
|
8
9
|
export declare function listAllRuntimes(env?: NodeJS.ProcessEnv): Runtime[];
|
package/dist/runtime/index.js
CHANGED
|
@@ -16,6 +16,7 @@ import { listRuntimes as listLmStudioRuntimes, resolveOverride } from "./lmstudi
|
|
|
16
16
|
import { defaultRuntimeSpec, installManagedRuntime, listManagedRuntimes, } from "./managed.js";
|
|
17
17
|
export { BACKENDS_DIR, LMSTUDIO_ROOT, listRuntimes as listLmStudioRuntimes } from "./lmstudio.js";
|
|
18
18
|
export { buildArgs, buildEnv, formatCommand } from "./args.js";
|
|
19
|
+
export { llamaCppRuntimeDriver, } from "./model-server-driver.js";
|
|
19
20
|
export { installManagedRuntime, removeManagedRuntime, listManagedRuntimes, listRuntimeDevices, verifyRuntimeExecutable, defaultRuntimeSpec, extractArchive, resolveRuntimeVariant, serverExeName, supportedVariants, DEFAULT_LLAMA_BUILD, listRuntimeReleases, latestRuntimeBuild, resolveLatestBuildOrPin, MissingAssetError, } from "./managed.js";
|
|
20
21
|
/** Every runtime available on this machine, managed first then LM Studio. */
|
|
21
22
|
export function listAllRuntimes(env = process.env) {
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Calibration, Profile } from "../config/schema.js";
|
|
2
|
+
import type { BrainPaths } from "../config/paths.js";
|
|
3
|
+
import type { Model, Runtime } from "../types.js";
|
|
4
|
+
export interface ModelServerLaunch {
|
|
5
|
+
executable: string;
|
|
6
|
+
args: string[];
|
|
7
|
+
cwd: string;
|
|
8
|
+
env: NodeJS.ProcessEnv;
|
|
9
|
+
command: string;
|
|
10
|
+
readinessPath: string;
|
|
11
|
+
propertiesPath: string | null;
|
|
12
|
+
formatLogLine(line: string): string;
|
|
13
|
+
}
|
|
14
|
+
export interface ModelServerDriverLaunchInput {
|
|
15
|
+
runtime: Runtime;
|
|
16
|
+
model: Model;
|
|
17
|
+
profile: Profile;
|
|
18
|
+
calibration: Calibration | null;
|
|
19
|
+
paths: BrainPaths;
|
|
20
|
+
host: string;
|
|
21
|
+
port: number;
|
|
22
|
+
logVerbosity: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Driver mechanics live here; the host owns process supervision, security,
|
|
26
|
+
* scheduler admission, status events, and the stable public endpoint.
|
|
27
|
+
*/
|
|
28
|
+
export interface ModelServerRuntimeDriver {
|
|
29
|
+
readonly id: string;
|
|
30
|
+
readonly displayName: string;
|
|
31
|
+
/** Native process name for engine-originated diagnostics. */
|
|
32
|
+
readonly processName: string;
|
|
33
|
+
describeProcessExit(input: {
|
|
34
|
+
code: number | null;
|
|
35
|
+
signal: NodeJS.Signals | null;
|
|
36
|
+
}): string;
|
|
37
|
+
describeLaunchError(error: Error): string;
|
|
38
|
+
createLaunch(input: ModelServerDriverLaunchInput): ModelServerLaunch;
|
|
39
|
+
}
|
|
40
|
+
/** The first driver preserves the existing managed llama.cpp launch exactly. */
|
|
41
|
+
export declare const llamaCppRuntimeDriver: ModelServerRuntimeDriver;
|
|
42
|
+
//# sourceMappingURL=model-server-driver.d.ts.map
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The narrow, observed seam between the Brain host and a model-server engine.
|
|
3
|
+
*
|
|
4
|
+
* This intentionally starts with launch and introspection only. A method joins
|
|
5
|
+
* this contract when the common host needs the behavior from more than one
|
|
6
|
+
* driver; naming every current llama.cpp flag as a generic operation would
|
|
7
|
+
* create a false lowest common denominator before a second engine exists.
|
|
8
|
+
*/
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import { mkdirSync } from "node:fs";
|
|
11
|
+
import { buildArgs, buildEnv, formatCommand } from "./args.js";
|
|
12
|
+
import { formatLlamaServerLog } from "../service/log-format.js";
|
|
13
|
+
/** The first driver preserves the existing managed llama.cpp launch exactly. */
|
|
14
|
+
export const llamaCppRuntimeDriver = {
|
|
15
|
+
id: "llama.cpp",
|
|
16
|
+
displayName: "llama.cpp",
|
|
17
|
+
processName: "llama-server",
|
|
18
|
+
describeProcessExit({ code, signal }) {
|
|
19
|
+
// 3221225781 == 0xC0000135 STATUS_DLL_NOT_FOUND: the vendor DLL trap.
|
|
20
|
+
const hint = code === 3221225781 ? " (missing runtime DLLs - the vendor directory was not on PATH)" : "";
|
|
21
|
+
return `llama-server exited with code ${code}${signal ? ` signal ${signal}` : ""}${hint}`;
|
|
22
|
+
},
|
|
23
|
+
describeLaunchError(error) {
|
|
24
|
+
return `could not launch llama-server: ${error.message}`;
|
|
25
|
+
},
|
|
26
|
+
createLaunch({ runtime, model, profile, calibration, paths, host, port, logVerbosity }) {
|
|
27
|
+
// llama.cpp enables scheduler-required slot erasure only when this existing
|
|
28
|
+
// directory is passed at launch. Failure to create it preserves the old
|
|
29
|
+
// behavior rather than making model startup fail for a cleanup feature.
|
|
30
|
+
const slotSavePath = path.join(paths.root, "slot-saves");
|
|
31
|
+
try {
|
|
32
|
+
mkdirSync(slotSavePath, { recursive: true });
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
/* launch without native slot actions */
|
|
36
|
+
}
|
|
37
|
+
const args = buildArgs({ ...profile, modelPath: model.modelPath, mmprojPath: model.mmprojPath }, { port, host, logVerbosity, slotSavePath }, model, calibration);
|
|
38
|
+
return {
|
|
39
|
+
executable: runtime.exe,
|
|
40
|
+
args,
|
|
41
|
+
cwd: runtime.dir,
|
|
42
|
+
env: buildEnv(runtime),
|
|
43
|
+
command: formatCommand(runtime, args),
|
|
44
|
+
readinessPath: "/health",
|
|
45
|
+
propertiesPath: "/props",
|
|
46
|
+
formatLogLine: formatLlamaServerLog,
|
|
47
|
+
};
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=model-server-driver.js.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type ChildProcess } from "node:child_process";
|
|
2
2
|
import { EventEmitter } from "node:events";
|
|
3
|
+
import { type ModelServerLaunch, type ModelServerRuntimeDriver } from "../runtime/index.js";
|
|
3
4
|
import { type BrainPaths } from "../config/paths.js";
|
|
4
5
|
import type { Model, Runtime } from "../types.js";
|
|
5
6
|
import type { Profile, ProfilesStore } from "../config/schema.js";
|
|
@@ -18,6 +19,8 @@ export declare const DEFAULT_INTERNAL_PORT = 20800;
|
|
|
18
19
|
export type SupervisorState = "stopped" | "starting" | "ready" | "failed" | "stopping";
|
|
19
20
|
export interface SupervisorOptions {
|
|
20
21
|
runtime: Runtime | null;
|
|
22
|
+
/** Native launch/introspection mechanics; lifecycle policy stays in this host. */
|
|
23
|
+
driver?: ModelServerRuntimeDriver;
|
|
21
24
|
internalPort?: number;
|
|
22
25
|
host?: string;
|
|
23
26
|
logVerbosity?: number;
|
|
@@ -44,7 +47,7 @@ export interface SupervisorStatus {
|
|
|
44
47
|
runtime: string;
|
|
45
48
|
}
|
|
46
49
|
/**
|
|
47
|
-
* Owns the
|
|
50
|
+
* Owns the model-server child process.
|
|
48
51
|
*
|
|
49
52
|
* The server always listens on a private port; `router.js` fronts it on a
|
|
50
53
|
* stable one so switching models never asks a client to reconnect elsewhere.
|
|
@@ -58,6 +61,7 @@ export declare class Supervisor extends EventEmitter {
|
|
|
58
61
|
readyTimeoutMs: number;
|
|
59
62
|
paths: BrainPaths;
|
|
60
63
|
getProfilesStore: () => ProfilesStore;
|
|
64
|
+
driver: ModelServerRuntimeDriver;
|
|
61
65
|
state: SupervisorState;
|
|
62
66
|
child: ChildProcess | null;
|
|
63
67
|
model: Model | null;
|
|
@@ -75,10 +79,11 @@ export declare class Supervisor extends EventEmitter {
|
|
|
75
79
|
* shell line is for reading, not for re-parsing.
|
|
76
80
|
*/
|
|
77
81
|
args: string[] | null;
|
|
78
|
-
|
|
82
|
+
launch: ModelServerLaunch | null;
|
|
83
|
+
constructor({ runtime, driver, internalPort, host, logVerbosity, readyTimeoutMs, paths, getProfilesStore, }: SupervisorOptions);
|
|
79
84
|
get upstreamBase(): string;
|
|
80
85
|
/**
|
|
81
|
-
* Add a host-operation event to the same in-process tail as
|
|
86
|
+
* Add a host-operation event to the same in-process tail as model-server output.
|
|
82
87
|
*
|
|
83
88
|
* Calibrate, sweep, and benchmark deliberately reuse this supervisor rather
|
|
84
89
|
* than creating invisible sidecar servers. Their lifecycle markers belong in
|
|
@@ -89,9 +94,9 @@ export declare class Supervisor extends EventEmitter {
|
|
|
89
94
|
/**
|
|
90
95
|
* Start (or restart) the server for a model + profile.
|
|
91
96
|
*
|
|
92
|
-
* This is the sole
|
|
93
|
-
* selected hosting profile here. Keeping it
|
|
94
|
-
* Jinja template and router-visible system addendum mandatory for every
|
|
97
|
+
* This is the sole model-server launch boundary, so it materializes the
|
|
98
|
+
* selected hosting profile here. Keeping it at this one driver call makes
|
|
99
|
+
* the Jinja template and router-visible system addendum mandatory for every
|
|
95
100
|
* caller, including future maintenance operations that start a sidecar.
|
|
96
101
|
*/
|
|
97
102
|
start(model: Model, profile: Profile): Promise<this>;
|
|
@@ -5,17 +5,15 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
5
5
|
};
|
|
6
6
|
var _Supervisor_instances, _Supervisor_setState, _Supervisor_log, _Supervisor_health;
|
|
7
7
|
import http from "node:http";
|
|
8
|
-
import path from "node:path";
|
|
9
|
-
import { mkdirSync } from "node:fs";
|
|
10
8
|
import { spawn } from "node:child_process";
|
|
11
9
|
import { EventEmitter } from "node:events";
|
|
12
|
-
import {
|
|
10
|
+
import { llamaCppRuntimeDriver, } from "../runtime/index.js";
|
|
13
11
|
import { resolveHostingProfileForLaunch } from "../config/hosting-profiles.js";
|
|
14
12
|
import { getCalibrationForBudget } from "../config/profiles.js";
|
|
15
13
|
import { resolveBrainPaths } from "../config/paths.js";
|
|
16
14
|
import { loadProfilesStore } from "../config/store.js";
|
|
17
15
|
import { usedBytes } from "../gpu.js";
|
|
18
|
-
import { formatBrainLog
|
|
16
|
+
import { formatBrainLog } from "./log-format.js";
|
|
19
17
|
const LOG_LINES_KEPT = 10000;
|
|
20
18
|
/**
|
|
21
19
|
* Default loopback port for the private llama-server child. Deliberately clear
|
|
@@ -29,16 +27,17 @@ const LOG_LINES_KEPT = 10000;
|
|
|
29
27
|
*/
|
|
30
28
|
export const DEFAULT_INTERNAL_PORT = 20800;
|
|
31
29
|
/**
|
|
32
|
-
* Owns the
|
|
30
|
+
* Owns the model-server child process.
|
|
33
31
|
*
|
|
34
32
|
* The server always listens on a private port; `router.js` fronts it on a
|
|
35
33
|
* stable one so switching models never asks a client to reconnect elsewhere.
|
|
36
34
|
*/
|
|
37
35
|
export class Supervisor extends EventEmitter {
|
|
38
|
-
constructor({ runtime, internalPort = DEFAULT_INTERNAL_PORT, host = "127.0.0.1", logVerbosity = 3, readyTimeoutMs = 300000, paths = resolveBrainPaths(), getProfilesStore = loadProfilesStore, }) {
|
|
36
|
+
constructor({ runtime, driver = llamaCppRuntimeDriver, internalPort = DEFAULT_INTERNAL_PORT, host = "127.0.0.1", logVerbosity = 3, readyTimeoutMs = 300000, paths = resolveBrainPaths(), getProfilesStore = loadProfilesStore, }) {
|
|
39
37
|
super();
|
|
40
38
|
_Supervisor_instances.add(this);
|
|
41
39
|
this.runtime = runtime;
|
|
40
|
+
this.driver = driver;
|
|
42
41
|
this.internalPort = internalPort;
|
|
43
42
|
this.host = host;
|
|
44
43
|
this.logVerbosity = logVerbosity;
|
|
@@ -57,12 +56,13 @@ export class Supervisor extends EventEmitter {
|
|
|
57
56
|
this.vramBaselineBytes = null;
|
|
58
57
|
this.command = null;
|
|
59
58
|
this.args = null;
|
|
59
|
+
this.launch = null;
|
|
60
60
|
}
|
|
61
61
|
get upstreamBase() {
|
|
62
62
|
return `http://${this.host}:${this.internalPort}`;
|
|
63
63
|
}
|
|
64
64
|
/**
|
|
65
|
-
* Add a host-operation event to the same in-process tail as
|
|
65
|
+
* Add a host-operation event to the same in-process tail as model-server output.
|
|
66
66
|
*
|
|
67
67
|
* Calibrate, sweep, and benchmark deliberately reuse this supervisor rather
|
|
68
68
|
* than creating invisible sidecar servers. Their lifecycle markers belong in
|
|
@@ -75,61 +75,53 @@ export class Supervisor extends EventEmitter {
|
|
|
75
75
|
/**
|
|
76
76
|
* Start (or restart) the server for a model + profile.
|
|
77
77
|
*
|
|
78
|
-
* This is the sole
|
|
79
|
-
* selected hosting profile here. Keeping it
|
|
80
|
-
* Jinja template and router-visible system addendum mandatory for every
|
|
78
|
+
* This is the sole model-server launch boundary, so it materializes the
|
|
79
|
+
* selected hosting profile here. Keeping it at this one driver call makes
|
|
80
|
+
* the Jinja template and router-visible system addendum mandatory for every
|
|
81
81
|
* caller, including future maintenance operations that start a sidecar.
|
|
82
82
|
*/
|
|
83
83
|
async start(model, profile) {
|
|
84
84
|
await this.stop();
|
|
85
85
|
if (!this.runtime) {
|
|
86
|
-
this.lastError =
|
|
86
|
+
this.lastError = `no ${this.driver.displayName} runtime available`;
|
|
87
87
|
__classPrivateFieldGet(this, _Supervisor_instances, "m", _Supervisor_setState).call(this, "failed", this.lastError);
|
|
88
88
|
throw new Error(this.lastError);
|
|
89
89
|
}
|
|
90
90
|
const runtime = this.runtime;
|
|
91
|
-
// The engine's slot save/erase directory, under the brain's home so it
|
|
92
|
-
// survives across model relaunches (the dir is persistent; the engine only
|
|
93
|
-
// ever uses it for the `action=erase` the scheduler issues on a handoff,
|
|
94
|
-
// which never writes a file). Created before the args are built because
|
|
95
|
-
// llama.cpp validates it exists at launch and throws otherwise.
|
|
96
|
-
const slotSavePath = path.join(this.paths.root, "slot-saves");
|
|
97
|
-
try {
|
|
98
|
-
mkdirSync(slotSavePath, { recursive: true });
|
|
99
|
-
}
|
|
100
|
-
catch {
|
|
101
|
-
/* the engine then starts without slot actions - the pre-fix behavior */
|
|
102
|
-
}
|
|
103
91
|
const launchProfile = resolveHostingProfileForLaunch(this.paths, this.getProfilesStore(), profile, model.family);
|
|
104
92
|
this.model = model;
|
|
105
93
|
this.profile = launchProfile;
|
|
106
94
|
this.lastError = null;
|
|
107
95
|
this.vramBaselineBytes = await usedBytes();
|
|
108
96
|
__classPrivateFieldGet(this, _Supervisor_instances, "m", _Supervisor_setState).call(this, "starting");
|
|
109
|
-
const
|
|
110
|
-
|
|
97
|
+
const launch = this.driver.createLaunch({
|
|
98
|
+
runtime,
|
|
99
|
+
model,
|
|
100
|
+
profile: launchProfile,
|
|
101
|
+
// The prompt-cache budget is derived from measured KV bytes/token, so the
|
|
102
|
+
// launch boundary is where it has to be resolved - nothing downstream of
|
|
103
|
+
// here can reach the calibration store.
|
|
104
|
+
calibration: getCalibrationForBudget(this.getProfilesStore(), model, launchProfile),
|
|
105
|
+
paths: this.paths,
|
|
111
106
|
host: this.host,
|
|
107
|
+
port: this.internalPort,
|
|
112
108
|
logVerbosity: this.logVerbosity,
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
// here can reach the calibration store.
|
|
118
|
-
getCalibrationForBudget(this.getProfilesStore(), model, launchProfile));
|
|
119
|
-
this.args = args;
|
|
120
|
-
this.command = formatCommand(runtime, args);
|
|
109
|
+
});
|
|
110
|
+
this.launch = launch;
|
|
111
|
+
this.args = launch.args;
|
|
112
|
+
this.command = launch.command;
|
|
121
113
|
__classPrivateFieldGet(this, _Supervisor_instances, "m", _Supervisor_log).call(this, formatBrainLog("model", `launching: ${this.command}`));
|
|
122
114
|
const started = Date.now();
|
|
123
|
-
this.child = spawn(
|
|
124
|
-
cwd:
|
|
125
|
-
env:
|
|
115
|
+
this.child = spawn(launch.executable, launch.args, {
|
|
116
|
+
cwd: launch.cwd,
|
|
117
|
+
env: launch.env,
|
|
126
118
|
windowsHide: true,
|
|
127
119
|
stdio: ["ignore", "pipe", "pipe"],
|
|
128
120
|
});
|
|
129
121
|
const onChunk = (chunk) => {
|
|
130
122
|
for (const line of String(chunk).split(/\r?\n/)) {
|
|
131
123
|
if (line.trim())
|
|
132
|
-
__classPrivateFieldGet(this, _Supervisor_instances, "m", _Supervisor_log).call(this,
|
|
124
|
+
__classPrivateFieldGet(this, _Supervisor_instances, "m", _Supervisor_log).call(this, launch.formatLogLine(line.trim()));
|
|
133
125
|
}
|
|
134
126
|
};
|
|
135
127
|
this.child.stdout?.on("data", onChunk);
|
|
@@ -143,15 +135,13 @@ export class Supervisor extends EventEmitter {
|
|
|
143
135
|
return;
|
|
144
136
|
}
|
|
145
137
|
exitedEarly = { code, signal };
|
|
146
|
-
|
|
147
|
-
const hint = code === 3221225781 ? " (missing runtime DLLs - the vendor directory was not on PATH)" : "";
|
|
148
|
-
this.lastError = `llama-server exited with code ${code}${signal ? ` signal ${signal}` : ""}${hint}`;
|
|
138
|
+
this.lastError = this.driver.describeProcessExit({ code, signal });
|
|
149
139
|
__classPrivateFieldGet(this, _Supervisor_instances, "m", _Supervisor_setState).call(this, "failed", this.lastError);
|
|
150
140
|
if (wasReady)
|
|
151
141
|
this.emit("crashed", this.lastError);
|
|
152
142
|
});
|
|
153
143
|
this.child.once("error", (error) => {
|
|
154
|
-
this.lastError =
|
|
144
|
+
this.lastError = this.driver.describeLaunchError(error);
|
|
155
145
|
__classPrivateFieldGet(this, _Supervisor_instances, "m", _Supervisor_setState).call(this, "failed", this.lastError);
|
|
156
146
|
});
|
|
157
147
|
// Poll /health until the model finishes loading.
|
|
@@ -164,7 +154,7 @@ export class Supervisor extends EventEmitter {
|
|
|
164
154
|
const used = await usedBytes();
|
|
165
155
|
if (used && used > peakVram)
|
|
166
156
|
peakVram = used;
|
|
167
|
-
const health = await __classPrivateFieldGet(this, _Supervisor_instances, "m", _Supervisor_health).call(this);
|
|
157
|
+
const health = await __classPrivateFieldGet(this, _Supervisor_instances, "m", _Supervisor_health).call(this, launch.readinessPath);
|
|
168
158
|
if (health) {
|
|
169
159
|
this.loadSeconds = (Date.now() - started) / 1000;
|
|
170
160
|
this.startedAt = new Date();
|
|
@@ -185,8 +175,11 @@ export class Supervisor extends EventEmitter {
|
|
|
185
175
|
}
|
|
186
176
|
/** Fetch /props from the running server (modalities, template caps, defaults). */
|
|
187
177
|
props() {
|
|
178
|
+
const pathname = this.launch?.propertiesPath;
|
|
179
|
+
if (!pathname)
|
|
180
|
+
return Promise.resolve(null);
|
|
188
181
|
return new Promise((resolve) => {
|
|
189
|
-
const req = http.get({ host: this.host, port: this.internalPort, path:
|
|
182
|
+
const req = http.get({ host: this.host, port: this.internalPort, path: pathname, timeout: 5000 }, (res) => {
|
|
190
183
|
let body = "";
|
|
191
184
|
res.on("data", (c) => (body += c));
|
|
192
185
|
res.on("end", () => {
|
|
@@ -263,9 +256,9 @@ _Supervisor_instances = new WeakSet(), _Supervisor_setState = function _Supervis
|
|
|
263
256
|
if (this.logLines.length > LOG_LINES_KEPT)
|
|
264
257
|
this.logLines.shift();
|
|
265
258
|
this.emit("log", line);
|
|
266
|
-
}, _Supervisor_health = function _Supervisor_health() {
|
|
259
|
+
}, _Supervisor_health = function _Supervisor_health(pathname) {
|
|
267
260
|
return new Promise((resolve) => {
|
|
268
|
-
const req = http.get({ host: this.host, port: this.internalPort, path:
|
|
261
|
+
const req = http.get({ host: this.host, port: this.internalPort, path: pathname, timeout: 2500 }, (res) => {
|
|
269
262
|
res.resume();
|
|
270
263
|
resolve(res.statusCode === 200);
|
|
271
264
|
});
|
package/package.json
CHANGED