簡體   English   中英

如何防止 NodeJS 子進程的管道流之間的 kill 信號傳播?

[英]How to prevent kill signal propagation between piped streams of NodeJS child processes?

問題描述

我有一個由 NodeJS 生成的子進程,其中 output stream (stdout) 需要連接到第二個 NodeJS 子進程輸入 stream (stdin)。

但是,有時第一個進程會被終止,在這種情況下,我想重新啟動該進程並將其 output stream 重新連接到相同的第二個進程輸入,而不必重新啟動第二個進程。

第一次嘗試

我首先嘗試連接 stdout 和 stdin,在第一個進程收到 kill 信號之前它工作正常:

const firstProc = cp.spawn('/some/proc/path', [/* args */])
const secondProc = cp.spawn('/ffmpeg/path', [/* args */])
firstProc.stdout.pipe(secondProc.stdin)

但是,一旦第一個進程收到終止信號,它就會傳播到第二個進程,第二個進程也會終止。

例如,在 NodeJS 主進程上,我能夠攔截SIGINT信號,但這似乎不適用於子進程:

process.on('SIGINT', () => {
  /* do something upon SIGINT kill signal */
})

問題總結

所以我的問題是:是否有可能在子進程傳輸到第二個進程之前攔截子進程的終止信號,“分離” stream 連接,啟動一個新進程和 pipe 其 output 到第二個進程的輸入 stream?

附加條款

我試圖在 stdout 和 stdin 之間添加一個雙工轉換 stream 但這似乎並沒有解決我的問題,因為它在輸入關閉時也會關閉。

我考慮過在兩個進程之間創建某種套接字連接,但我從來沒有做過那樣的事情,而且我有點擔心增加的復雜性。

如果有更簡單的方法來處理我的情況,我很樂意知道! 感謝您的任何想法!

請參閱https://nodejs.org/api/stream.html#readablepipedestination-options

默認情況下,當源Readable stream 發出'end'時,在目標Writable stream 上調用stream.end() ,以便目標不再可寫。 要禁用此默認行為,可以將end選項作為false傳遞,從而使目標 stream 保持打開狀態

所以你正在尋找類似的東西

const secondProc = cp.spawn('/ffmpeg/path', [/* args */]);
function writeForever() {
  const firstProc = cp.spawn('/some/proc/path', [/* args */])
  firstProc.stdout.pipe(secondProc.stdin, { end: false });
  firstProc.stdout.on('end', writeForever); // just spawn a new firstProc and continue…
}
writeForever();

由於我確實使用Angular框架,所以我對RXJS已經很習慣了,這使得這種流式傳輸任務變得非常容易。

如果您要處理大量流,我建議您將RXJSRXJS-stream一起使用。

生成的代碼如下所示:

import { concat, of } from 'rxjs';
import { rxToStream, streamToRx } from 'rxjs-stream';

const concatedStreams$ = concat([
  streamToRx(cp.spawn('/some/proc/path', [/* args */])),
  //of('End of first, start of second'), // Optional
  streamToRx(cp.spawn('/ffmpeg/path', [/* args */])),
]);

rxToStream(concatedStreams$).pipe(process.stdout);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM