diff --git a/api/src/api/v2.js b/api/src/api/v2.js index 6cf2106..725f0a3 100644 --- a/api/src/api/v2.js +++ b/api/src/api/v2.js @@ -50,6 +50,7 @@ const SIGNALS = [ function get_job(job_info, available_runtimes) { let { language, + version, args, stdin, files, @@ -79,8 +80,10 @@ function get_job(job_info, available_runtimes) { } } - const rt = available_runtimes.find(rt => - [...rt.aliases, rt.language].includes(rt.language) + const rt = available_runtimes.find( + rt => + [...rt.aliases, rt.language].includes(language) && + (version === rt.version || version === '*') ); if (rt === undefined) { diff --git a/api/src/bin/pistond.js b/api/src/bin/pistond.js index 1712c36..c07e08d 100755 --- a/api/src/bin/pistond.js +++ b/api/src/bin/pistond.js @@ -43,7 +43,22 @@ expressWs(app); `nix eval --json ${config.flake_path}#pistonRuntimeSets.${config.runtime_set} --apply builtins.attrNames` ) .toString(); - const runtime_names = JSON.parse(runtimes_data); + const runtime_names_unordered = JSON.parse(runtimes_data); + + const mainstream_runtimes_data = cp + .execSync( + `nix eval --json ${config.flake_path}#pistonMainstreamRuntimes` + ) + .toString(); + const mainstream_runtimes = JSON.parse(mainstream_runtimes_data).filter(runtime => + runtime_names_unordered.includes(runtime) + ); + const runtime_names = [ + ...mainstream_runtimes, + ...runtime_names_unordered.filter( + runtime => !mainstream_runtimes.includes(runtime) + ), + ]; logger.info('Loading the runtimes from the flakes'); const runtimes = runtime_names.map(runtime_name => { diff --git a/api/src/job.js b/api/src/job.js index bf62126..ab12402 100644 --- a/api/src/job.js +++ b/api/src/job.js @@ -28,6 +28,9 @@ setInterval(() => { }, 10); class Job { + #active_timeouts; + #active_parent_processes; + constructor({ runtime, files, args, stdin, timeouts, memory_limits }) { this.uuid = uuidv4(); @@ -49,6 +52,9 @@ class Job { this.stdin += '\n'; } + this.#active_timeouts = []; + this.#active_parent_processes = []; + this.timeouts = timeouts; this.memory_limits = memory_limits; @@ -113,6 +119,28 @@ class Job { this.logger.debug('Primed job'); } + exit_cleanup() { + for (const timeout of this.#active_timeouts) { + clear_timeout(timeout); + } + this.#active_timeouts = []; + this.logger.debug('Cleared the active timeouts'); + + for (const proc of this.#active_parent_processes) { + proc.stderr.destroy(); + if (!proc.stdin.destroyed) { + proc.stdin.end(); + proc.stdin.destroy(); + } + proc.stdout.destroy(); + } + this.#active_parent_processes = []; + this.logger.debug('Destroyed parent processes writables'); + + this.cleanup_processes(); + this.logger.debug(`Finished exit cleanup`); + } + async safe_call(file, args, timeout, memory_limit, eventBus = null) { return new Promise((resolve, reject) => { const nonetwork = config.disable_networking ? ['nosocket'] : []; @@ -149,6 +177,8 @@ class Job { detached: true, //give this process its own process group }); + this.#active_parent_processes.push(proc); + if (eventBus === null) { proc.stdin.write(this.stdin); proc.stdin.end(); @@ -170,6 +200,7 @@ class Job { process.kill(proc.pid, 'SIGKILL'); }, timeout)) || null; + this.#active_timeouts.push(kill_timeout); proc.stderr.on('data', async data => { if (eventBus !== null) { @@ -195,24 +226,14 @@ class Job { } }); - const exit_cleanup = () => { - clear_timeout(kill_timeout); - - proc.stderr.destroy(); - proc.stdout.destroy(); - - this.cleanup_processes(); - this.logger.debug(`Finished exit cleanup`); - }; - proc.on('exit', (code, signal) => { - exit_cleanup(); + this.exit_cleanup(); resolve({ stdout, stderr, code, signal, output }); }); proc.on('error', err => { - exit_cleanup(); + this.exit_cleanup(); reject({ error: err, stdout, stderr, output }); }); @@ -431,7 +452,7 @@ class Job { async cleanup() { this.logger.info(`Cleaning up job`); - this.cleanup_processes(); // Run process janitor, just incase there are any residual processes somehow + this.exit_cleanup(); // Run process janitor, just incase there are any residual processes somehow await this.cleanup_filesystem(); remaining_job_spaces++; diff --git a/flake.nix b/flake.nix index d53fc00..2b9c50d 100644 --- a/flake.nix +++ b/flake.nix @@ -65,6 +65,13 @@ "bash-only" = runtimeList ["bash"]; "none" = { }; }; + pistonMainstreamRuntimes = [ + "mono-csharp" + "python3" + "node-javascript" + "node-typescript" + "mono-basic" + ]; legacyPackages."${system}" = rec { nosocket = (import ./nosocket { inherit pkgs; }).package; diff --git a/runtimes/python2.nix b/runtimes/python2.nix index 9b89a20..4a8b306 100644 --- a/runtimes/python2.nix +++ b/runtimes/python2.nix @@ -7,6 +7,8 @@ in piston.mkRuntime { aliases = [ "py2" + "python" + "py" ]; run = '' @@ -22,4 +24,4 @@ in piston.mkRuntime { }; }) ]; -} \ No newline at end of file +} diff --git a/runtimes/python3.nix b/runtimes/python3.nix index 9dc2682..3831bca 100644 --- a/runtimes/python3.nix +++ b/runtimes/python3.nix @@ -8,6 +8,7 @@ in piston.mkRuntime { aliases = [ "py3" "py" + "python" ]; run = '' @@ -23,4 +24,4 @@ in piston.mkRuntime { }; }) ]; -} \ No newline at end of file +}