我们正在使用FFI节点模块从Node.js服务器使用c ++ dll。 C ++ dll公开了Node.js服务器正在使用的许多功能。
在某些特殊情况下,C ++ dll具有卡住的特征。到目前为止,我们还没有一种机制可以从C ++ dll中进行修复。因此,即将到来的请求将无法得到解决,因为dll是单线程的,一次只能接受一个请求。
之所以必须使用cluster-worker拓扑是因为我们想从外部控制dll。
我们创建了固定数量的叉子/工人,它们在一个池中。对于每个传入的请求,我们将请求分配给一个新的工作程序,并将该工作程序与dll一起使用。每当看到工人花费的时间超过“健康”的时间时,我们都希望杀死它。
我们面临一个特定的问题,如果该工人因C ++ dll无法响应而陷入困境,我们将无法杀死该工人。这是必需的,因为c ++ dll中存在未处理的情况。
我们引用了Node.js集群模块的代码- https://nodejs.org/api/cluster.html#cluster_worker_process
这是我们的代码段-
server_fork.js
var chalk = require( "chalk" );
var cluster = require( "cluster" );
var os = require( "os" );
if ( cluster.isMaster ) {
console.log( chalk.red( "[Cluster]" ), "Master process is now running.", process.pid );
for ( var i = 0, coreCount = 2; i < coreCount ; i++ ) {
var worker = cluster.fork();
}
function messageHandler(msg) {
console.log('messageHandler')
if (msg.cmd && msg.cmd === 'notifyRequest') {
numReqs += 1;
}
}
cluster.on(
"exit",
function handleExit( worker, code, signal ) {
console.log( chalk.yellow( "[Cluster]" ), "Worker has died.", worker.process.pid );
console.log( chalk.yellow( "[Cluster]" ), "Death was suicide:", worker.exitedAfterDisconnect );
var worker = cluster.fork();
console.log('new thread');
}
);
cluster.on(
"message",
function handleExit( worker, code, signal ) {
let timeout
if (code.cmd == 'started'){
worker.toBeKilled = true
timeout = setTimeout(() => {
if(worker.toBeKilled){
try{
console.log('inside worker to be killed')
// worker.disconnect()
worker.kill()
//process.exit(0)
// process.exit()
}catch(err){
console.log('err',err)
}
}
}, 2000);
} else {
worker.toBeKilled = false
}
}
);
function messageHandler(msg) {
if (msg.cmd && msg.cmd === 'notifyRequest') {
console.log('notifyRequest');
}
}
} else {
require( "./server" );
console.log( chalk.red( "[Worker]" ), "Worker has started.", process.pid );
}
server.js
const Koa = require('koa');
var mount = require('koa-mount');
var serve = require('koa-static');
var bodyParser = require('koa-bodyparser');
var koaBody = require('koa-body');
var api = require('./../src/modules/bvp/router.js');
var jwt = require('koa-jwt');
const app = new Koa();
var hbs = require('koa-hbs');
const convert = require('koa-convert');
const co = require('co');
app.use(convert(hbs.middleware({
viewPath: __dirname + '/../src/views',
})));
app.use(async (ctx, next) => {
const render = ctx.render;
ctx.render = async function _convertedRender () {
return co.call(ctx, render.apply(ctx, arguments));
}
await next();
});
if (!process.env.NODE_ENV || process.env.NODE_ENV === 'devlopment') {
app.use(mount('/swagger', serve(`${process.cwd()}/../swagger`)))
}
app.use(koaBody());
app.use(bodyParser());
app.use(api.routes());
app.listen(3000, function() {
console.log('server started on port 3000');
});
module.exports = app;
controller.js
var som_lib = require('som_lib.js');
const Promise = require('promise');
async function simulate(ctx) {
var arr = [];
process.send({ cmd: 'started' });
var output = som_lib.playLeague();
process.send({ cmd: 'end' });
ctx.body = output;
}
module.exports = {
simulate: simulate
}
在超时的情况下,当我们试图杀死该特定工人时,我们会收到以下错误-
err { Error: kill ESRCH
at exports._errnoException (util.js:1050:11)
at process.kill (internal/process.js:188:13)
at Timeout.setTimeout [as _onTimeout] (C:\Data\projects\BVP_backend - Copy\bin\server_fork.js:65:33)
at ontimeout (timers.js:386:14)
at tryOnTimeout (timers.js:250:5)
at Timer.listOnTimeout (timers.js:214:5) code: 'ESRCH', errno: 'ESRCH', syscall: 'kill' }
我们已经在Express框架中提到了类似的问题-链接 Can't kill a specific worker in Node JS cluster