handle usage stats
This commit is contained in:
parent
647bc3a7c7
commit
a40b581ee9
|
@ -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"
|
||||||
}
|
}
|
|
@ -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 });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue