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!'
});
});
}
}
2
Answers
As https://stackoverflow.com/users/740553/mike-pomax-kamermans noted, Javascript is single threaded, meaning long running synchronous operations will block your thread while executing. It’s not clear what library you’re using to perform your training, but check to see if they have any asynchronous methods for training. Also, you’re using the synchronous version of the
fs.writeFile
method, which again will block your thread while executing. To remedy this, use the async version:Use child_process to perform training on a separate process. Here is how it can be implemented:
trainMaster.js
trainWorker.js
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:
Otherwise you will need some different approach, like spreading workers across multiple machines and using message queue to distribute the work between them.