Node.js
Sfide di prestazione
Ricerca…
Elaborazione di query a esecuzione prolungata con nodo
Poiché il nodo è a thread singolo, è necessario risolvere il problema in caso di calcoli a lunga esecuzione.
Nota: questo è l'esempio "pronto per l'esecuzione". Solo, non dimenticare di ottenere jQuery e installare i moduli richiesti.
Logica principale di questo esempio:
- Il cliente invia una richiesta al server.
- Il server avvia la routine in un'istanza del nodo separato e invia una risposta immediata con l'ID dell'attività correlata.
- Il cliente invia continuamente assegni a un server per gli aggiornamenti di stato dell'ID attività specificato.
Struttura del progetto:
project
│ package.json
│ index.html
│
├───js
│ main.js
│ jquery-1.12.0.min.js
│
└───srv
│ app.js
├─── models
│ task.js
└─── tasks
data-processor.js
app.js:
var express = require('express');
var app = express();
var http = require('http').Server(app);
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var childProcess= require('child_process');
var Task = require('./models/task');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(express.static(__dirname + '/../'));
app.get('/', function(request, response){
response.render('index.html');
});
//route for the request itself
app.post('/long-running-request', function(request, response){
//create new task item for status tracking
var t = new Task({ status: 'Starting ...' });
t.save(function(err, task){
//create new instance of node for running separate task in another thread
taskProcessor = childProcess.fork('./srv/tasks/data-processor.js');
//process the messages comming from the task processor
taskProcessor.on('message', function(msg){
task.status = msg.status;
task.save();
}.bind(this));
//remove previously openned node instance when we finished
taskProcessor.on('close', function(msg){
this.kill();
});
//send some params to our separate task
var params = {
message: 'Hello from main thread'
};
taskProcessor.send(params);
response.status(200).json(task);
});
});
//route to check is the request is finished the calculations
app.post('/is-ready', function(request, response){
Task
.findById(request.body.id)
.exec(function(err, task){
response.status(200).json(task);
});
});
mongoose.connect('mongodb://localhost/test');
http.listen('1234');
task.js:
var mongoose = require('mongoose');
var taskSchema = mongoose.Schema({
status: {
type: String
}
});
mongoose.model('Task', taskSchema);
module.exports = mongoose.model('Task');
data-processor.js:
process.on('message', function(msg){
init = function(){
processData(msg.message);
}.bind(this)();
function processData(message){
//send status update to the main app
process.send({ status: 'We have started processing your data.' });
//long calculations ..
setTimeout(function(){
process.send({ status: 'Done!' });
//notify node, that we are done with this task
process.disconnect();
}, 5000);
}
});
process.on('uncaughtException',function(err){
console.log("Error happened: " + err.message + "\n" + err.stack + ".\n");
console.log("Gracefully finish the routine.");
});
index.html:
<!DOCTYPE html>
<html>
<head>
<script src="./js/jquery-1.12.0.min.js"></script>
<script src="./js/main.js"></script>
</head>
<body>
<p>Example of processing long-running node requests.</p>
<button id="go" type="button">Run</button>
<br />
<p>Log:</p>
<textarea id="log" rows="20" cols="50"></textarea>
</body>
</html>
main.js:
$(document).on('ready', function(){
$('#go').on('click', function(e){
//clear log
$("#log").val('');
$.post("/long-running-request", {some_params: 'params' })
.done(function(task){
$("#log").val( $("#log").val() + '\n' + task.status);
//function for tracking the status of the task
function updateStatus(){
$.post("/is-ready", {id: task._id })
.done(function(response){
$("#log").val( $("#log").val() + '\n' + response.status);
if(response.status != 'Done!'){
checkTaskTimeout = setTimeout(updateStatus, 500);
}
});
}
//start checking the task
var checkTaskTimeout = setTimeout(updateStatus, 100);
});
});
});
package.json:
{
"name": "nodeProcessor",
"dependencies": {
"body-parser": "^1.15.2",
"express": "^4.14.0",
"html": "0.0.10",
"mongoose": "^4.5.5"
}
}
Disclaimer: questo esempio ha lo scopo di darti un'idea di base. Per usarlo nell'ambiente di produzione, ha bisogno di miglioramenti.
Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow