Merge pull request #632 from ssahai/bugfix/catch_error
Handle process kills gracefully
This commit is contained in:
commit
a7fa1b47fe
|
@ -146,7 +146,7 @@ class Job {
|
||||||
'--nofile=' + this.runtime.max_open_files,
|
'--nofile=' + this.runtime.max_open_files,
|
||||||
'--fsize=' + this.runtime.max_file_size,
|
'--fsize=' + this.runtime.max_file_size,
|
||||||
];
|
];
|
||||||
|
|
||||||
const timeout_call = [
|
const timeout_call = [
|
||||||
'timeout',
|
'timeout',
|
||||||
'-s',
|
'-s',
|
||||||
|
@ -158,7 +158,7 @@ class Job {
|
||||||
prlimit.push('--as=' + memory_limit);
|
prlimit.push('--as=' + memory_limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
const proc_call = [
|
const proc_call = [
|
||||||
'nice',
|
'nice',
|
||||||
...timeout_call,
|
...timeout_call,
|
||||||
...prlimit,
|
...prlimit,
|
||||||
|
@ -204,7 +204,16 @@ class Job {
|
||||||
(timeout >= 0 &&
|
(timeout >= 0 &&
|
||||||
set_timeout(async _ => {
|
set_timeout(async _ => {
|
||||||
this.logger.info(`Timeout exceeded timeout=${timeout}`);
|
this.logger.info(`Timeout exceeded timeout=${timeout}`);
|
||||||
process.kill(proc.pid, 'SIGKILL');
|
try {
|
||||||
|
process.kill(proc.pid, 'SIGKILL');
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
// Could already be dead and just needs to be waited on
|
||||||
|
this.logger.debug(
|
||||||
|
`Got error while SIGKILLing process ${proc}:`,
|
||||||
|
e
|
||||||
|
);
|
||||||
|
}
|
||||||
}, timeout)) ||
|
}, timeout)) ||
|
||||||
null;
|
null;
|
||||||
this.#active_timeouts.push(kill_timeout);
|
this.#active_timeouts.push(kill_timeout);
|
||||||
|
@ -214,7 +223,16 @@ class Job {
|
||||||
event_bus.emit('stderr', data);
|
event_bus.emit('stderr', data);
|
||||||
} else if (stderr.length > this.runtime.output_max_size) {
|
} else if (stderr.length > this.runtime.output_max_size) {
|
||||||
this.logger.info(`stderr length exceeded`);
|
this.logger.info(`stderr length exceeded`);
|
||||||
process.kill(proc.pid, 'SIGKILL');
|
try {
|
||||||
|
process.kill(proc.pid, 'SIGKILL');
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
// Could already be dead and just needs to be waited on
|
||||||
|
this.logger.debug(
|
||||||
|
`Got error while SIGKILLing process ${proc}:`,
|
||||||
|
e
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
stderr += data;
|
stderr += data;
|
||||||
output += data;
|
output += data;
|
||||||
|
@ -226,7 +244,16 @@ class Job {
|
||||||
event_bus.emit('stdout', data);
|
event_bus.emit('stdout', data);
|
||||||
} else if (stdout.length > this.runtime.output_max_size) {
|
} else if (stdout.length > this.runtime.output_max_size) {
|
||||||
this.logger.info(`stdout length exceeded`);
|
this.logger.info(`stdout length exceeded`);
|
||||||
process.kill(proc.pid, 'SIGKILL');
|
try {
|
||||||
|
process.kill(proc.pid, 'SIGKILL');
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
// Could already be dead and just needs to be waited on
|
||||||
|
this.logger.debug(
|
||||||
|
`Got error while SIGKILLing process ${proc}:`,
|
||||||
|
e
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
stdout += data;
|
stdout += data;
|
||||||
output += data;
|
output += data;
|
||||||
|
@ -254,7 +281,7 @@ class Job {
|
||||||
if (this.state !== job_states.PRIMED) {
|
if (this.state !== job_states.PRIMED) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'Job must be in primed state, current state: ' +
|
'Job must be in primed state, current state: ' +
|
||||||
this.state.toString()
|
this.state.toString()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,22 +298,22 @@ class Job {
|
||||||
const { emit_event_bus_result, emit_event_bus_stage } =
|
const { emit_event_bus_result, emit_event_bus_stage } =
|
||||||
event_bus === null
|
event_bus === null
|
||||||
? {
|
? {
|
||||||
emit_event_bus_result: () => {},
|
emit_event_bus_result: () => { },
|
||||||
emit_event_bus_stage: () => {},
|
emit_event_bus_stage: () => { },
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
emit_event_bus_result: (stage, result, event_bus) => {
|
emit_event_bus_result: (stage, result, event_bus) => {
|
||||||
const { error, code, signal } = result;
|
const { error, code, signal } = result;
|
||||||
event_bus.emit('exit', stage, {
|
event_bus.emit('exit', stage, {
|
||||||
error,
|
error,
|
||||||
code,
|
code,
|
||||||
signal,
|
signal,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
emit_event_bus_stage: (stage, event_bus) => {
|
emit_event_bus_stage: (stage, event_bus) => {
|
||||||
event_bus.emit('stage', stage);
|
event_bus.emit('stage', stage);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.runtime.compiled) {
|
if (this.runtime.compiled) {
|
||||||
this.logger.debug('Compiling');
|
this.logger.debug('Compiling');
|
||||||
|
@ -352,9 +379,9 @@ class Job {
|
||||||
const [_, ruid, euid, suid, fuid] = uid_line.split(/\s+/);
|
const [_, ruid, euid, suid, fuid] = uid_line.split(/\s+/);
|
||||||
|
|
||||||
const [_1, state, user_friendly] = state_line.split(/\s+/);
|
const [_1, state, user_friendly] = state_line.split(/\s+/);
|
||||||
|
|
||||||
const proc_id_int = parse_int(proc_id);
|
const proc_id_int = parse_int(proc_id);
|
||||||
|
|
||||||
// Skip over any processes that aren't ours.
|
// Skip over any processes that aren't ours.
|
||||||
if (ruid != this.uid && euid != this.uid) return -1;
|
if (ruid != this.uid && euid != this.uid) return -1;
|
||||||
|
|
||||||
|
@ -362,7 +389,7 @@ class Job {
|
||||||
// Zombie process, just needs to be waited, regardless of the user id
|
// Zombie process, just needs to be waited, regardless of the user id
|
||||||
if (!to_wait.includes(proc_id_int))
|
if (!to_wait.includes(proc_id_int))
|
||||||
to_wait.push(proc_id_int);
|
to_wait.push(proc_id_int);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// We should kill in all other state (Sleep, Stopped & Running)
|
// We should kill in all other state (Sleep, Stopped & Running)
|
||||||
|
@ -397,7 +424,7 @@ class Job {
|
||||||
// Then clear them out of the process tree
|
// Then clear them out of the process tree
|
||||||
try {
|
try {
|
||||||
process.kill(proc, 'SIGKILL');
|
process.kill(proc, 'SIGKILL');
|
||||||
} catch {
|
} catch (e) {
|
||||||
// Could already be dead and just needs to be waited on
|
// Could already be dead and just needs to be waited on
|
||||||
this.logger.debug(
|
this.logger.debug(
|
||||||
`Got error while SIGKILLing process ${proc}:`,
|
`Got error while SIGKILLing process ${proc}:`,
|
||||||
|
|
Loading…
Reference in New Issue