如何在Mean Stack中运行subprocess

我有一个使用nodejs,angularjs和expressjs的Mean应用程序。

在这里,我已经从angular度控制器调用我的服务器如下

Angular Controller.js

$http.post('/sample', $scope.sample).then(function (response) { -- -- } 

并在Server.js如下

 app.post('/sample', userController.postsample); 

在这里,我正在做mongodb的操作,从上面的代码后的示例

在这里,我碰到了如何做我的计算部分,就像我有一个大的计算,需要一些时间(假设1小时)来完成。 所以从客户端我会触发angular度控制器的计算。

我的问题是计算应该单独运行,以便其他UI和其他页面的操作不应该被中断。

我已经看到了nodejs中的subprocess,但我不明白如何从控制器的subprocess触发或执行它,如果它在app.post中获取请求,那么是否有可能访问其他页面。

编辑:

我已经计划在孵化一个child_process,但我有另一个问题继续上述。

可以考虑应用程序包含3个用户和2个用户同时访问应用程序。 我的情况是,如果第一个人触发了child_process名称作为first operation ,并且正在处理中,那么此时第二个人需要触发该stream程名称作为2nd operation因为他还需要计算。 这里我的问题是

  1. 如果另一个人启动了spawn命令,会发生什么情况。 如果挂起或保持队列或两者并行执行。
  2. 如果第二个操作在队列中,那么什么时候开始操作。
  3. 如果第二个操作在队列中,那么我怎么知道有多less人在某个时间点排队呢?

任何人都可以帮助解决。

注意:这个问题已经编辑 – 请参阅下面的更新。

你有几个select去做。

最简单的方法是从Express控制器产生subprocess,一旦完成计算就会将响应返回给客户端,但是如果时间太长,那么套接字超时等问题就会出现。服务器或客户端(如果您不使用服务器上的“同步”function和客户端上的同步AJAX),但连接挂起时间过长会出现问题。

另一个select是对这些请求使用WebSocket或Socket.io。 客户端可以向服务器发送一条消息,要求开始一些计算,服务器可以产生subprocess,执行其他操作,当subprocess返回时,只是将消息发送给客户端。 这样做的缺点是一种新的沟通方式,但至less不会出现超时问题。

要了解如何将WebSocket或Socket.io与Express结合使用,请参阅此答案,其中包含WebSocket和Socket.io的示例 – 实际上它非常简单:

  • socket.io和websockets之间的区别

无论哪种方式,为了产生一个subprocess,你可以使用:

  • spawn
  • exec
  • execFile
  • fork

从核心的child_process模块。 只要确保永远不要使用名称中的“同步”function来执行你想要做的事情,因为这会阻止你的服务器在整个等待孩子完成的时候提供其他的请求 – 这可能是你的一个小时的情况下,但即使这将是一秒钟,它仍然可以完全破坏并发。

看文档:

更新

一些更新的编辑问题。 考虑这个例子的shell脚本:

 #!/bin/sh sleep 5 date -Is 

等待5秒钟,打印当前时间。 现在考虑这个例子Node应用程序:

 let child_process = require('child_process'); let app = require('express')(); app.get('/test', (req, res) => { child_process.execFile('./script.sh', (err, data) => { if (err) { return res.status(500).send('Error'); } res.send(data); }); }); app.listen(3344, () => console.log('Listening on 3344')); 

或者使用ES2017语法:

 let child_process = require('mz/child_process'); let app = require('express')(); app.get('/test', async (req, res) => { try { res.send((await child_process.execFile('./script.sh'))[0]); } catch (err) { res.status(500).send('Error'); } }); app.listen(3344, () => console.log('Listening on 3344')); 

它在GET /test上为请求运行该shell脚本并返回结果。

现在同时启动两个请求:

 curl localhost:3344/test & curl localhost:3344/test & curl localhost:3344/test & 

看看会发生什么 如果返回的时间相差5秒,并且以5秒为间隔接连一个响应,则操作排队。 如果你同时获得所有的响应,或多或less有相同的时间戳,那么这些都是并行的。

有时候最好做一个这样的实验来看看会发生什么。