Skip to content

Commit f42bf73

Browse files
committed
Handle failed start
1 parent 891fa75 commit f42bf73

File tree

5 files changed

+172
-215
lines changed

5 files changed

+172
-215
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"lint": "TIMING=1 NODE_OPTIONS=\"--max-old-space-size=2048\" scripts/run-script.js -w modules -j 4 -e \"! ls .eslintrc* > /dev/null || npx eslint ./ --ext .ts --ext .js --cache --cache-strategy=content\"",
3434
"lint:uncached": "find . -name .eslintcache -delete && yarn lint",
3535
"start": "DEVELOPMENT=true node dist/sth/bin/hub.js",
36-
"start:dev": "DEVELOPMENT=true ts-node packages/sth/src/bin/hub.ts",
36+
"start:dev": "ts-node packages/sth/src/bin/hub.ts",
3737
"start:dev:cli": "DEVELOPMENT=true ts-node packages/cli/src/bin/index.ts",
3838
"install:clean": "yarn clean && yarn clean:modules && yarn install",
3939
"postinstall": "scripts/run-script.js -v -w modules install:deps",

packages/adapters/src/process-instance-adapter.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class ProcessInstanceAdapter implements
3535
sthConfig: STHConfiguration;
3636

3737
processPID: number = -1;
38+
exitCode = -1;
3839
id?: string | undefined;
3940

4041
private runnerProcess?: ChildProcess;
@@ -171,6 +172,11 @@ class ProcessInstanceAdapter implements
171172

172173
runnerProcess.unref();
173174

175+
runnerProcess.on("exit", (code) => {
176+
this.exitCode = Number(code) || -1;
177+
this.logger.info("Runner exit code", code);
178+
});
179+
174180
this.crashLogStreams = Promise.all([runnerProcess.stdout, runnerProcess.stderr].map(streamToString));
175181

176182
this.runnerProcess = runnerProcess;
@@ -186,8 +192,15 @@ class ProcessInstanceAdapter implements
186192

187193
async waitUntilExit(_config: InstanceConfig, _instanceId: string, _sequenceInfo: SequenceInfo): Promise<ExitCode> {
188194
if (this.runnerProcess) {
195+
189196
const [statusCode, signal] = await new Promise<[number | null, NodeJS.Signals | null]>(
190-
(res) => this.runnerProcess?.on("exit", (code, sig) => res([code, sig]))
197+
(res) => {
198+
if (this.exitCode > -1) {
199+
res([this.exitCode, null]);
200+
}
201+
202+
this.runnerProcess?.on("exit", (code, sig) => res([code, sig]))
203+
}
191204
);
192205

193206
this.logger.trace("Runner process exited", this.runnerProcess?.pid);

packages/host/src/lib/csi-controller.ts

Lines changed: 4 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
MessageUtilities
77
} from "@scramjet/model";
88
import { development } from "@scramjet/sth-config";
9-
import { CommunicationChannel as CC, RunnerExitCode, RunnerMessageCode } from "@scramjet/symbols";
9+
import { CommunicationChannel as CC, RunnerMessageCode } from "@scramjet/symbols";
1010
import {
1111
APIRoute,
1212
AppConfig,
@@ -45,6 +45,7 @@ import { ObjLogger } from "@scramjet/obj-logger";
4545
import { RunnerConnectInfo } from "@scramjet/types/src/runner-connect";
4646
import { cancellableDefer, CancellablePromise, defer, promiseTimeout, TypedEmitter } from "@scramjet/utility";
4747
import { ReasonPhrases } from "http-status-codes";
48+
import { mapRunnerExitCode } from "./utils";
4849

4950
/**
5051
* @TODO: Runner exits after 10secs and k8s client checks status every 500ms so we need to give it some time
@@ -239,7 +240,7 @@ export class CSIController extends TypedEmitter<Events> {
239240

240241
async main() {
241242
this.status = InstanceStatus.RUNNING;
242-
this.logger.trace("Instance started", this.status);
243+
this.logger.trace("Main. Current status:", this.status);
243244

244245
let code = -1;
245246

@@ -315,7 +316,7 @@ export class CSIController extends TypedEmitter<Events> {
315316
};
316317

317318
this.instancePromise = instanceMain()
318-
.then((exitcode) => this.mapRunnerExitCode(exitcode))
319+
.then((exitcode) => mapRunnerExitCode(exitcode, this.sequence))
319320
.catch((error) => {
320321
this.logger.error("Instance promise rejected", error);
321322
this.initResolver?.rej(error);
@@ -336,74 +337,6 @@ export class CSIController extends TypedEmitter<Events> {
336337
});
337338
}
338339

339-
// eslint-disable-next-line complexity
340-
private mapRunnerExitCode(exitcode: number): Promise<
341-
{ message: string, exitcode: number, status: InstanceStatus }
342-
> {
343-
// eslint-disable-next-line default-case
344-
switch (exitcode) {
345-
case RunnerExitCode.INVALID_ENV_VARS: {
346-
return Promise.reject({
347-
message: "Runner was started with invalid configuration. This is probably a bug in STH.",
348-
exitcode: RunnerExitCode.INVALID_ENV_VARS,
349-
status: InstanceStatus.ERRORED
350-
});
351-
}
352-
case RunnerExitCode.PODS_LIMIT_REACHED: {
353-
return Promise.reject({
354-
message: "Instance limit reached",
355-
exitcode: RunnerExitCode.PODS_LIMIT_REACHED,
356-
status: InstanceStatus.ERRORED
357-
});
358-
}
359-
case RunnerExitCode.INVALID_SEQUENCE_PATH: {
360-
return Promise.reject({
361-
message: `Sequence entrypoint path ${this.sequence.config.entrypointPath} is invalid. ` +
362-
"Check `main` field in Sequence package.json",
363-
exitcode: RunnerExitCode.INVALID_SEQUENCE_PATH,
364-
status: InstanceStatus.ERRORED
365-
});
366-
}
367-
case RunnerExitCode.SEQUENCE_FAILED_ON_START: {
368-
return Promise.reject({
369-
message: "Sequence failed on start",
370-
exitcode: RunnerExitCode.SEQUENCE_FAILED_ON_START,
371-
status: InstanceStatus.ERRORED
372-
});
373-
}
374-
case RunnerExitCode.SEQUENCE_FAILED_DURING_EXECUTION: {
375-
return Promise.reject({
376-
message: "Sequence failed during execution",
377-
exitcode: RunnerExitCode.SEQUENCE_FAILED_DURING_EXECUTION,
378-
status: InstanceStatus.ERRORED
379-
});
380-
}
381-
case RunnerExitCode.SEQUENCE_UNPACK_FAILED: {
382-
return Promise.reject({
383-
message: "Sequence unpack failed",
384-
exitcode: RunnerExitCode.SEQUENCE_UNPACK_FAILED,
385-
status: InstanceStatus.ERRORED
386-
});
387-
}
388-
case RunnerExitCode.KILLED: {
389-
return Promise.resolve({
390-
message: "Instance killed", exitcode: RunnerExitCode.KILLED, status: InstanceStatus.COMPLETED
391-
});
392-
}
393-
case RunnerExitCode.STOPPED: {
394-
return Promise.resolve({
395-
message: "Instance stopped", exitcode: RunnerExitCode.STOPPED, status: InstanceStatus.COMPLETED
396-
});
397-
}
398-
}
399-
400-
if (exitcode > 0) {
401-
return Promise.reject({ message: "Runner failed", exitcode, status: InstanceStatus.ERRORED });
402-
}
403-
404-
return Promise.resolve({ message: "Instance completed", exitcode, status: InstanceStatus.COMPLETED });
405-
}
406-
407340
async cleanup() {
408341
await this.instanceAdapter.cleanup();
409342

0 commit comments

Comments
 (0)