2012-04-06 2 views
5

Я хочу добавить некоторые утилит администратора к небольшому веб-приложению, например «Резервная база данных». Пользователь нажмет на кнопку, и ответ HTTP немедленно вернется, хотя потенциально длительный процесс был запущен в фоновом режиме.«Появление потока» в стиле node.js

В Java это, вероятно, будет реализовано путем нереста независимого потока в Scala с помощью Актера. Но что такое подходящая идиома в node.js? (код снипета оценен)

Теперь я перечитываю документы, это действительно вопрос узла 101, но это в значительной степени, где я нахожусь ... во всяком случае, чтобы прояснить, что это основной сценарий:

function onRequest(request, response) { 
    doSomething(); 
    response.writeHead(202, headers); 
    response.end("doing something"); 
} 

function doSomething(){ 
    // long-running operation 
} 

Я хочу, чтобы ответ немедленно вернулся, оставив doSomething() бегущим в фоновом режиме.

Хорошо, учитывая однопотоковую модель узла, которая не представляется возможной, не порождая другой дочерний процесс уровня ОС. Мое недоразумение.

В моем коде, что мне нужно для резервного копирования, в основном основано на I/O, поэтому узел должен обрабатывать это с помощью приятного асинхронного способа. Я думаю, что я сделаю, это переместить doSomething после response.end, посмотреть, как это происходит.

+0

Надеюсь, вы просмотрели документацию. http://nodejs.org/docs/v0.4.7/api/index.html Я думаю, что это зависит от характера вашего процесса, но посмотрите на Child Process. – supertopi

+0

Спасибо. Кажется, моя проблема была укоренена в глубоком непонимании того, как работает узел :). Детский процесс был тем, что я имел в виду, хотя и не самым простым решением, см. Ответ Джо ниже. – danja

ответ

3

Я не вижу проблемы. Все, что вам нужно сделать, это иметь doSomething() начать асинхронную операцию. Он немедленно вернется, ваш onRequest напишет ответ обратно, и клиент получит сообщение «ОК, я начал».

function doSomething() { 
    openDatabaseConnection(connectionString, function(conn) { 
     // This is called some time later, once the connection is established. 
     // Now you can tell the database to back itself up. 
    }); 
} 

doSomething не будет просто сидеть там, пока соединение с базой данных не установлена, или ждать, пока вы говорите это, чтобы поддержать. Он сразу же вернется, зарегистрировав обратный вызов, который будет запущен позже. За кулисами ваша библиотека базы данных, вероятно, создает для вас некоторые потоки, чтобы сделать работу async так, как она должна быть, но ваш код не должен беспокоиться об этом; вы сразу возвращаетесь, сразу же отправляйте ответ клиенту, а асинхронный код продолжает работать асинхронно.

(Это на самом деле больше работы, чтобы сделать этот бег синхронно. - Вы должны передать свой response объект в doSomething, и имеют doSomething сделать response.end вызов внутри внутреннего обратного вызова, после того, как резервная копия делается, конечно, это не что вы хотите сделать здесь, вы хотите немедленно вернуться, что и будет делать ваш код.)

+0

Спасибо. Кажется, моя проблема была укоренена в глубоком непонимании того, как работает узел :) – danja

5

Поскольку супертопи сказал, что вы можете взглянуть на Child process. Но я думаю, что это повредит производительности вашего сервера, если это произойдет много раз подряд. Тогда я думаю, вам стоит их поставить в очередь. Я думаю, вы должны взглянуть на asynchronous message queues, чтобы обрабатывать ваши вакансии в автономном режиме (распределенные). Некоторые (только для обозначения двух) примеров очередей сообщений - beanstalkd, gearman.

+0

Спасибо. Кажется, моя проблема была укоренена в глубоком непонимании того, как работает узел :) Использование очереди, хотя кажется очень хорошей идеей. – danja

Смежные вопросы