i'm doing an artificial intelligence training and that method takes to long (5 minutes) and while my method is running my backend stay blocked waiting my method finish, is there any solution for it?
train: (answersIA, search, res) => {
const path = `api/IA/${search.id}`;
if (answersIA.length == 0) {
return null;
}
else {
answersIA = answersIA.filter(answer => answer.score);
answersIA = answersService.setOutput(answersIA);
answersIA = answersService.encodeAll(IAServiceTrain.adjustSize(answersIA));
net.train(answersIA, {
errorThresh: 0.005,
iterations: 100,
log: true,
logPeriod: 10,
learningRate: 0.3
});
mkdirp(path, (err) => {
if (err) throw 'No permission to create trained-net file';
fs.writeFileSync(`${path}/trained-net.js`, `${net.toFunction().toString()};`);
res.json({
message: 'Trained!'
});
});
}
}
Use child_process to perform training on a separate process. Here is how it can be implemented:
trainMaster.js
const fork = require('child_process').fork;
exports.train = (arguments, callback) => {
const worker = fork(`${__dirname}/trainWorker.js`);
worker.send(arguments);
worker.on('message', result => {
callback(result);
worker.kill();
});
}
trainWorker.js
process.on('message', arguments => {
const result = train(arguments)
process.send(result);
});
function train(arguments) { /* your training logic */ }
So when you call train
on trainMaster.js from your main application it doesn't do actual training and doesn't block the event loop. Instead it creates a new process, waits for it to perform all the heavy lifting and then terminates it.
This approach should work fine if the number of simultaneous trainings is less than the number of CPU on your machine. From Node.js docs:
It is important to keep in mind that spawned Node.js child processes are independent of the parent with exception of the IPC communication channel that is established between the two. Each process has its own memory, with their own V8 instances. Because of the additional resource allocations required, spawning a large number of child Node.js processes is not recommended.
Otherwise you will need some different approach, like spreading workers across multiple machines and using message queue to distribute the work between them.