config.js: timeout, overrides

This commit is contained in:
Brikaa 2021-10-01 21:41:09 +02:00
parent 7d90cddf27
commit 4870441574
2 changed files with 76 additions and 4 deletions

View File

@ -109,8 +109,8 @@ function get_job(body){
stdin: stdin || "", stdin: stdin || "",
files, files,
timeouts: { timeouts: {
run: run_timeout || 3000, run: run_timeout || config.run_timeout,
compile: compile_timeout || 10000, compile: compile_timeout || config.compile_timeout,
}, },
memory_limits: { memory_limits: {
run: run_memory_limit || config.run_memory_limit, run: run_memory_limit || config.run_memory_limit,
@ -228,7 +228,7 @@ router.post('/execute', async (req, res) => {
return res.status(200).send(result); return res.status(200).send(result);
}catch(error){ }catch(error){
return res.status(400).json(error); return res.status(400).json(error.to_string());
} }
}); });

View File

@ -2,6 +2,46 @@ const fss = require('fs');
const Logger = require('logplease'); const Logger = require('logplease');
const logger = Logger.create('config'); const logger = Logger.create('config');
function parse_overrides(overrides) {
try {
return JSON.parse(overrides);
}
catch (e) {
return null;
}
}
function validate_overrides(overrides, options) {
for (let language in overrides) {
for (let key in overrides[language]) {
if (
![
'max_process_count', 'max_open_files', 'max_file_size',
'compile_memory_limit', 'run_memory_limit', 'compile_timeout',
'run_timeout', 'output_max_size'
].includes(key)
) {
logger.error(`Invalid overridden option: ${key}`);
return false;
}
let option = options.find((o) => o.key == key);
let parser = option.parser;
let raw = overrides[language][key];
let value = parser(raw);
let validators = option.validators;
for (let validator of validators) {
let response = validator(value, raw);
if (response !== true) {
logger.error(`Failed to validate overridden option: ${key}`, response);
return false;
}
}
overrides[language][key] = value;
}
}
return overrides;
}
const options = [ const options = [
{ {
key: 'log_level', key: 'log_level',
@ -91,6 +131,22 @@ const options = [
parser: parse_int, parser: parse_int,
validators: [(x, raw) => !is_nan(x) || `${raw} is not a number`], validators: [(x, raw) => !is_nan(x) || `${raw} is not a number`],
}, },
{
key: 'compile_timeout',
desc:
'Max time allowed for compile stage in milliseconds',
default: 10000, // 10 seconds
parser: parse_int,
validators: [(x, raw) => !is_nan(x) || `${raw} is not a number`],
},
{
key: 'run_timeout',
desc:
'Max time allowed for run stage in milliseconds',
default: 3000, // 3 seconds
parser: parse_int,
validators: [(x, raw) => !is_nan(x) || `${raw} is not a number`],
},
{ {
key: 'compile_memory_limit', key: 'compile_memory_limit',
desc: desc:
@ -120,6 +176,16 @@ const options = [
default: 64, default: 64,
parser: parse_int, parser: parse_int,
validators: [(x) => x > 0 || `${x} cannot be negative`] validators: [(x) => x > 0 || `${x} cannot be negative`]
},
{
key: 'limit_overrides',
desc: 'Per-language exceptions in JSON format for each of:\
max_process_count, max_open_files, max_file_size, compile_memory_limit,\
run_memory_limit, compile_timeout, run_timeout, output_max_size',
default: {},
parser: parse_overrides,
validators: [(x) => !!x || `Invalid JSON format for the overrides\n${x}`]
// More validation is done after the configs are loaded
} }
]; ];
@ -138,7 +204,7 @@ options.forEach(option => {
const parsed_val = parser(env_val); const parsed_val = parser(env_val);
const value = env_val || option.default; const value = parsed_val || option.default;
option.validators.for_each(validator => { option.validators.for_each(validator => {
let response = null; let response = null;
@ -158,10 +224,16 @@ options.forEach(option => {
config[option.key] = value; config[option.key] = value;
}); });
let overrides = validate_overrides(config.limit_overrides, options)
errored = errored || !overrides;
if (errored) { if (errored) {
process.exit(1); process.exit(1);
} }
config.limit_overrides = overrides;
console.log(config.limit_overrides);
logger.info('Configuration successfully loaded'); logger.info('Configuration successfully loaded');
module.exports = config; module.exports = config;