在节点

时间:2016-06-02 16:54:10

标签: node.js

我有一段需要取消的代码,但是无法对工作进行分块并发布回调以便能够在继续处理之前检查事件。然而,它可以定期检查一些信号。在伪代码中,如下所示(实际代码要复杂得多):

while (true) {
  if (isCancelled()) return false;
  doSomeWork();
  if (isFinished()) return true;
}

实施isCancelled是一项挑战。大多数通知需要返回事件循环才能获取事件。我尝试在控制进程和Node之间使用套接字,并调用非阻塞的read,如果没有数据(https://nodejs.org/dist/latest-v4.x/docs/api/stream.html#stream_readable_read_size)则返回null,但在我的测试中,这似乎也是要求在出现任何新数据之前返回事件循环。 (即上面的isCancelled从来都不是真的,除非在上面的代码开始运行时已经有数据等待了。)

如果没有用OS原语编写本机模块,那么在处理过程中是否存在同步检查Node中的外部信号/通知的任何其他经过验证的模式。

注意:实际的总工作时间最长为500毫秒,理想情况下可以在几毫秒内取消,因此内部缓冲的任何通道都可能太慢。此外,这需要在Windows上运行,因此任何* IX类型的信号都不是一个选项。

3 个答案:

答案 0 :(得分:2)

底层的AsyncListener API仍然在这里,而且不会去任何地方 - https://github.com/nodejs/node/search?q=async_wrap.enable

但是,在当前状态下,它对您的方案无济于事。 isCancelled()必须联系外部环境并以同步方式检查。

执行此操作的一种简单方法是在主进程中创建命名管道,然后使用require('fs').statSync('\\\\.\\pipe\\signal_pipe_123')检查子进程中是否存在管道。

您需要几毫秒的延迟,管道速度更快。对于一些轶事证据,我刚刚在我的Windows笔记本电脑上检查过,管道创建需要0.035毫秒,而命名管道上的同步统计数据为0.25毫秒 - 对于相关用例来说已经足够了。

答案 1 :(得分:0)

类似黑客的解决方案是通过文件系统发送信号。例如,您可以创建名为取消 - taskid 的文件,而isCancelled()只需要检查该文件是否存在。但不确定,它是否适合你的时间限制。

答案 2 :(得分:0)

解决问题的最佳方法可能是通过共享内存使用进程间通信。例如,请参阅shm包。我从来没有使用它(说实话,我从来没有使用过node.js),但它声称可以在Windows上运行。