【问题标题】:How to run child process in Mean Stack如何在平均堆栈中运行子进程
【发布时间】:2017-09-01 15:57:37
【问题描述】:

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

在这里,我从下面的角度控制器调用了我的服务器

Angular Controller.js

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

         --
         --     
        }

Server.js中如下

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

我在上面的代码中的 post sample 中使用 mongodb 进行操作。

在这里,我对如何进行计算部分感到震惊,就像我有一个需要一些时间(假设 1 小时)才能完成的大计算。所以从客户端我会从我的角度控制器触发计算。

我的问题是计算应该分开运行,这样其他页面的其他UI和操作不应该被打断。

我在 nodejs 中看到过该子进程,但我不明白如何从控制器的子进程中触发或执行该子进程,如果它在 app.post 中获得请求,那么是否可以访问其他页面。

编辑:

我计划在 Spawn 中创建一个 child_process,但我在继续上述操作时遇到了另一个问题。

假设应用程序包含 3 个用户,并且有 2 个用户同时访问该应用程序。 我的情况是,如果第一个人触发了 child_process 名称,它为first operation,并且它正在处理中,此时第二个人需要触发它为2nd operation 的进程名称,因为他还需要计算。 这是我的问题

  1. 如果另一个人启动 spawn 命令会发生什么。如果它挂起或保留在队列中或两者并行执行。
  2. 如果第二个操作在队列中,那么它将何时开始操作。
  3. 如果第二个操作在队列中,那么我如何知道某个时间点有多少人在队列中

谁能帮忙解决。

【问题讨论】:

  • 我宁愿有两条服务器路由:``` POST /sample GET /sample-end ``` 第一个会做计算,第二个会做: - 计算未完成 - > 返回一条消息说尚未 - 计算未完成 -> 返回结果。您的控制器已经与 UI 分离。不时调用第二条路线。

标签: javascript angularjs node.js mongodb express


【解决方案1】:

注意:问题已编辑 - 请参阅下面的更新。

你几乎没有选择。

最直接的方法是从您的 Express 控制器生成子进程,一旦计算完成,它将向客户端返回响应,但如果需要很长时间,那么您可能会遇到套接字超时等问题。这将不要阻塞你的服务器或客户端(如果你不使用服务器上的“同步”功能和客户端上的同步 AJAX)但是你会遇到连接挂起这么久的问题。

另一种选择是对这些请求使用 WebSocket 或 Socket.io。客户端可以向服务器发布一条消息,它希望开始一些计算,服务器可以生成子进程,做其他事情,当子进程返回时,只需将消息发送给客户端。这样做的缺点是一种新的通信方式,但至少不会出现超时问题。

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

无论哪种方式,您都可以使用生成子进程:

  • spawn
  • exec
  • execFile
  • fork

来自核心child_process 模块。只要确保从不使用任何名称中带有“Sync”的功能来执行您想要执行的操作,因为这些功能会阻止您的服务器在等待孩子完成的整个过程中服务其他请求 -在您的情况下,这可能是一个小时,但即使是一秒钟,它仍然可能完全破坏并发性。

查看文档:

更新

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

#!/bin/sh
sleep 5
date -Is

等待 5 秒并打印当前时间。现在考虑这个示例节点应用程序:

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 秒的间隔收到一个又一个响应,则操作将排队。如果您同时获得所有响应且时间戳大致相同,那么这些响应都是并行运行的。

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

【讨论】:

猜你喜欢
  • 2013-12-15
  • 2018-11-29
  • 1970-01-01
  • 2017-03-21
  • 1970-01-01
  • 2016-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多