config.js: timeout, overrides

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

View File

@ -109,8 +109,8 @@ function get_job(body){
stdin: stdin || "",
files,
timeouts: {
run: run_timeout || 3000,
compile: compile_timeout || 10000,
run: run_timeout || config.run_timeout,
compile: compile_timeout || config.compile_timeout,
},
memory_limits: {
run: run_memory_limit || config.run_memory_limit,
@ -228,7 +228,7 @@ router.post('/execute', async (req, res) => {
return res.status(200).send(result);
}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 = 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 = [
{
key: 'log_level',
@ -91,6 +131,22 @@ const options = [
parser: parse_int,
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',
desc:
@ -120,6 +176,16 @@ const options = [
default: 64,
parser: parse_int,
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 value = env_val || option.default;
const value = parsed_val || option.default;
option.validators.for_each(validator => {
let response = null;
@ -158,10 +224,16 @@ options.forEach(option => {
config[option.key] = value;
});
let overrides = validate_overrides(config.limit_overrides, options)
errored = errored || !overrides;
if (errored) {
process.exit(1);
}
config.limit_overrides = overrides;
console.log(config.limit_overrides);
logger.info('Configuration successfully loaded');
module.exports = config;