我的主要Node实例分叉一个工作进程,该进程通过IPC(使用内置节点process.send()
和process.on('message'...
)接受消息,这些消息是包含要添加到{{3的新作业的信息的对象}}。然后它处理这些工作。
我的主要Node实例调用类似这样的东西:
worker.send({jobType:'filesystem', operation: 'delete', path: fileDir});
并且worker实例执行以下操作:
jobs.create(message.jobType, message).save();
jobs.process('filesystem', function(job, done) {
fs.delete(job.data.path, function(err) {
done(err);
});
});
并且作业成功完成。
如何在作业完成后在我的主节点实例中获得类似回调的功能?如何从工作程序实例向主节点实例返回一些结果?
答案 0 :(得分:1)
我相信我解决了这个问题,但如果有人能改进我的解决方案或提供更好的解决方案,我会留下未解决的问题。
当您使用Kue在单独的进程中处理作业时,您不能简单地在作业完成时执行回调。这是两个进程之间通信的示例。我本来希望使用Kue自动提供每个作业的ID(我认为它与Redis中收到的id相同)但app.js需要知道作业的ID才会被发送给工作者以便它可以在收到消息时匹配id。
<强> app.js 强>
var child = require('child_process');
var async = require('async');
var worker = child.fork("./worker.js");
//When a message is received, search activeJobs for it, call finished callback, and delete the job
worker.on('message', function(m) {
for(var i = 0; i < activeJobs.length; i++) {
if(m.jobId == activeJobs[i].jobId) {
activeJobs[i].finished(m.err, m.results);
activeJobs.splice(i,1);
break;
}
}
});
// local job system
var newJobId = 0;
var activeJobs = [];
function Job(input, callback) {
this.jobId = newJobId;
input.jobId = newJobId;
newJobId++;
activeJobs.push(this);
worker.send(input);
this.finished = function(err, results) {
callback(err, results);
}
}
var deleteIt = function(req, res) {
async.series([
function(callback) {
// An *EXAMPLE* asynchronous task that is passed off to the worker to be processed
// and requires a callback (because of async.series)
new Job({
jobType:'filesystem',
title:'delete project directory',
operation: 'delete',
path: '/deleteMe'
}, function(err) {
callback(err);
});
},
//Delete it from the database
function(callback) {
someObject.remove(function(err) {
callback(err);
});
},
],
function(err) {
if(err) console.log(err);
});
};
<强> worker.js 强>
var kue = require('kue');
var fs = require('fs-extra');
var jobs = kue.createQueue();
//Jobs that are sent arrive here
process.on('message', function(message) {
if(message.jobType) {
var job = jobs.create(message.jobType, message).save();
} else {
console.error("Worker:".cyan + " [ERROR] No jobType specified, message ignored".red);
}
});
jobs.process('filesystem', function(job, done) {
if(job.data.operation == 'delete') {
fs.delete(job.data.path, function(err) {
notifyFinished(job.data.jobId, err);
done(err);
});
}
});
function notifyFinished(id, error, results) {
process.send({jobId: id, status: 'finished', error: error, results: results});
}