handle usage stats

This commit is contained in:
Всеволод 2024-03-02 16:14:09 +03:00
parent 647bc3a7c7
commit a40b581ee9
2 changed files with 58 additions and 4 deletions

View File

@ -14,7 +14,8 @@
"node-fetch": "^2.6.1", "node-fetch": "^2.6.1",
"semver": "^7.3.4", "semver": "^7.3.4",
"uuid": "^8.3.2", "uuid": "^8.3.2",
"waitpid": "git+https://github.com/HexF/node-waitpid.git" "waitpid": "git+https://github.com/HexF/node-waitpid.git",
"pidusage": "^3.0.2"
}, },
"license": "MIT" "license": "MIT"
} }

View File

@ -8,6 +8,7 @@ const globals = require('./globals');
const fs = require('fs/promises'); const fs = require('fs/promises');
const fss = require('fs'); const fss = require('fs');
const wait_pid = require('waitpid'); const wait_pid = require('waitpid');
const pidusage = require('pidusage');
const job_states = { const job_states = {
READY: Symbol('Ready to be primed'), READY: Symbol('Ready to be primed'),
@ -136,6 +137,32 @@ class Job {
this.logger.debug('Destroyed processes writables'); this.logger.debug('Destroyed processes writables');
} }
get_stats(pid) {
// https://www.npmjs.com/package/pidusage
return new Promise((resolve, reject) => {
pidusage(pid, {
usePs: true,
}, (err, stat) => {
if (err) {
this.logger.error(`Error getting process stats:`, err);
reject(err);
}
let res = {
'cpu': stat.cpu,
'memory': stat.memory,
'ctime': stat.ctime,
'elapsed': stat.elapsed,
'timestamp': stat.timestamp,
};
this.logger.debug(`Got stats:`, res);
resolve(res);
});
});
}
async safe_call(file, args, timeout, memory_limit, event_bus = null) { async safe_call(file, args, timeout, memory_limit, event_bus = null) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const nonetwork = config.disable_networking ? ['nosocket'] : []; const nonetwork = config.disable_networking ? ['nosocket'] : [];
@ -171,6 +198,7 @@ class Job {
var stdout = ''; var stdout = '';
var stderr = ''; var stderr = '';
var output = ''; var output = '';
var stats = [];
const proc = cp.spawn(proc_call[0], proc_call.splice(1), { const proc = cp.spawn(proc_call[0], proc_call.splice(1), {
env: { env: {
@ -186,6 +214,10 @@ class Job {
this.#active_parent_processes.push(proc); this.#active_parent_processes.push(proc);
this.get_stats(proc.pid).then(stat => {
stats.push(stat);
});
if (event_bus === null) { if (event_bus === null) {
proc.stdin.write(this.stdin); proc.stdin.write(this.stdin);
proc.stdin.end(); proc.stdin.end();
@ -203,6 +235,9 @@ class Job {
const kill_timeout = const kill_timeout =
(timeout >= 0 && (timeout >= 0 &&
set_timeout(async _ => { set_timeout(async _ => {
this.get_stats(proc.pid).then(stat => {
stats.push(stat);
});
this.logger.info(`Timeout exceeded timeout=${timeout}`); this.logger.info(`Timeout exceeded timeout=${timeout}`);
try { try {
process.kill(proc.pid, 'SIGKILL'); process.kill(proc.pid, 'SIGKILL');
@ -237,6 +272,10 @@ class Job {
stderr += data; stderr += data;
output += data; output += data;
} }
this.get_stats(proc.pid).then(stat => {
stats.push(stat);
});
}); });
proc.stdout.on('data', async data => { proc.stdout.on('data', async data => {
@ -258,6 +297,10 @@ class Job {
stdout += data; stdout += data;
output += data; output += data;
} }
this.get_stats(proc.pid).then(stat => {
stats.push(stat);
});
}); });
proc.on('exit', () => this.exit_cleanup()); proc.on('exit', () => this.exit_cleanup());
@ -265,14 +308,24 @@ class Job {
proc.on('close', (code, signal) => { proc.on('close', (code, signal) => {
this.close_cleanup(); this.close_cleanup();
resolve({ stdout, stderr, code, signal, output }); if (stats.length !== 0) {
stats = stats[stats.length - 1];
}
this.logger.debug(`Last stats:`, stats);
resolve({ stdout, stderr, code, signal, output, stats });
}); });
proc.on('error', err => { proc.on('error', err => {
this.exit_cleanup(); this.exit_cleanup();
this.close_cleanup(); this.close_cleanup();
reject({ error: err, stdout, stderr, output }); if (stats.length !== 0) {
stats = stats[stats.length - 1];
}
this.logger.debug(`Last stats:`, stats);
reject({ error: err, stdout, stderr, output, stats });
}); });
}); });
} }