2015-10-29 4 views
28

Я узловое приложение, которое сделано нерест (дочерний процесса), чтобы и приложения, приложение имеет хост и порт:Node и прибудете расслоение плотного набора данных из другого процесса

var exec = require('child_process').spawn; 
var child = exec('start app'); 
console.log("Child Proc ID " + child.pid) 
child.stdout.on('data', function(data) { 
    console.log('stdout: ' + data); 
}); 
child.stderr.on('data', function(data) { 
    console.log('stdout: ' + data); 
}); 
child.on('close', function(code) { 
    console.log('closing code: ' + code); 
}); 

какое-то приложение запустится сразу, а некоторые приложение займет около раз 10 - 20 секунд, пока они не начнут.

Теперь я использую HTTP-прокси узла для запуска приложения, и проблема заключается в том, что Im получает ошибку, когда использование хочет запустить приложение до его запуска и запуска. Любая идея как-то я могу решить эту проблему?

proxy.on('error', function (err, req, res) { 
    res.end('Cannot run app'); 
}); 

Btw, я не могу отправить ответ 500 в прокси-ошибке из-за ограничения нашей структуры. Любая другая идея, как я могу отслеживать приложение может быть, с некоторым тайм-аут, чтобы увидеть погоду это отправить ответ 200.

UPDATE - Пример из моей логики

httpProxy = require('http-proxy'); 
var proxy = httpProxy.createProxyServer({}); 
http.createServer(function (req, res) { 
    console.log("App proxy new port is: " + 5000) 
    res.end("Request received on " + 5000); 
}).listen(5000); 

function proxyRequest(req, res) { 
    var hostname = req.headers.host.split(":")[0]; 
    proxy.web(req, res, { 
     target: 'http://' + hostname + ':' + 5000 
    }); 

    proxy.on('error', function (err, req, res) { 
     res.end('Cannot run app'); 
    }); 
} 
+0

Вы упоминаете, что у вас есть рамки ограничений - можете ли вы перейти к более подробным сведениям? Трудно понять, какие решения доступны вам, если мы не знаем, что можем и чего не можем сделать.У вас есть контроль над дочерним процессом (-ами), который порождается? –

+0

Что вы ожидаете, если сообщение отправлено и приложение еще не доступно? – Koder

ответ

1

Что вам нужно для прослушивания первого ответа на ваш прокси-сервера и посмотрите его код состояния, чтобы определить, было ли ваше приложение успешно запущено или нет. Вот как вы это делаете:

proxy.on('proxyRes', function (proxyRes, req, res) { 
    // Your target app is definitely up and running now because it just sent a response; 
    // Use the status code now to determine whether the app started successfully or not 
    var status = res.statusCode; 
}); 

Надеюсь, это поможет.

+0

Спасибо, но когда и как я должен это делать? Предположим, что я поместил ваш код и пользователь нажимал на браузер, чтобы запустить приложение, которое все еще не в порядке, так что сначала он увидит ошибку, так как я могу это преодолеть? может быть, вы специалист в этой теме, и я что-то пропустил :) Спасибо! –

+0

Итак, если пользователь открывает браузер, и браузер делает запрос к вашему приложению, тогда прокси должно выдать событие «proxyRes». Если ваше приложение не готово, браузер не получит ответ до его появления. Поэтому я думаю, что это должно сработать. – idancali

+0

Спасибо, но ошибка не придет раньше? –

1

Не уверен, что это имеет смысл. В вашем основном приложении опыт должен начинаться с html-страницы, и каждый дочерний процесс должен иметь собственный загрузчик.

Итак, в основном вам нужен обработчик http, который задерживает запрос до тех пор, пока дочерний процесс не будет готов. Так что просто сделайте и ajax-вызов из html, и покажите анимацию загрузки, пока служба не будет готова.

//Ajax call for each process and update the UI accordingly 
$.get('/services/status/100').then(function(resp) { 
    $('#service-100').html(resp.responseText); 
}) 

//server side code (express syntax) 
app.get('/services/status/:id ', function(req,res) { 
    // Check if service is ready 
    serviceManager.isReady(req.params.id, function(err, serviceStats) { 
     if(err) { 
      //do logic err here , maybe notify the ui if an error occurred 
      res.send(err); 
      return; 
     } 
     // notify the ui , that the service is ready to run , and hide loader 
     res.send(serviceStats); 
    }); 
}) 
1

Я не уверен, я понимаю вопрос правильно, но вы хотите ждать, пока дочерний процесс крутиться по запросу, и вы хотите этот запрос ждать этого дочернего процесса, а затем будет отправить к нему? Если это так простое решение будет использовать что-то вроде этого

var count = 0;//Counter to check 
    var maxDelay = 45;//In Seconds 
    var checkEverySeconds = 1;//In seconds 
    async.whilst(
     function() { 
      return count < maxDelay; 
     }, 
     function (callback) { 
      count++; 
      self.getAppStatus(apiKey, function (err, status) { 
       if (status != 200) { 
        return setTimeout(callback, checkEverySeconds * 1000); 

       } 
       continueWithRequest(); 

      }); 
     }, 
     function (err) { 
      if (err) { 
       return continueWithRequest(new Error('process cannot spin!')); 
      } 
     } 
    ); 

функция continueWithRequest() направит запрос в дочернем процессе и getAppStatus возвратит 200, когда дочерний процесс начался, и некоторые другие код, если это не так. Общая идея заключается в том, что каждый раз проверяется каждый раз, если процесс выполняется, и через 45 секунд, если нет, он вернет ошибку. Время ожидания и интервалы проверки можно легко отрегулировать. Это немного грубо, но будет работать для задержки запроса, а setTimeout запустит новый стек и не будет блокироваться. Надеюсь это поможет.

1

Если вы знаете (вокруг), сколько времени приложение требуется, чтобы получить и работает, просто добавьте setTimeout(proxyRequest, <Time it takes the app to start in MS>)

(Есть, скорее всего, более умные/сложные решения, но этот самый простой.)

1

Почему бы не использовать event-emitter или messenger?

var eventEmitter = require('event-emitter') 
var childStart = require('./someChildProcess').start() 

if (childStart !== true) { 
     eventEmitter.emit('progNotRun', { 
      data: data 
     }) 
} 

function proxyRequest(req, res) { 

    var hostname = req.headers.host.split(":")[0]; 
    proxy.web(req, res, { 
     target: 'http://' + hostname + ':' + 5000 
    }); 

    eventEmitter.on('progNotRun', function(data) { 
     res.end('Cannot run app', data); 
    }) 
}