web-dev-qa-db-ja.com

Node.jsプロセスが強制的に終了しないようにする方法は?

TL; DR

Node.jsプロセスを強制的に実行し続ける、つまりイベントループが空にならないようにしてプロセスを終了させないための最良の方法は何ですか?私が思いついた最良の解決策はこれでした:

const SOME_HUGE_INTERVAL = 1 << 30;
setInterval(() => {}, SOME_HUGE_INTERVAL);

インターバル期間を十分に長く保つと、過度の妨害を引き起こすことなくインターバルを実行し続けます。

それを行うためのより良い方法はありますか?

質問の長いバージョン

Edge.js を使用して、.NET内のDLLから呼び出すことができるようにコールバック関数を登録するNode.jsスクリプトがあります。この関数は、1秒間に1回呼び出され、コンソールに出力される単純なシーケンス番号を送信します。

Edge.jsの部分は問題なく、すべてが機能しています。私の唯一の問題は、Node.jsプロセスがスクリプトを実行した後、処理するイベントが不足することです。イベントループが空の状態で終了するだけで、DLLからコールバックを受信できるように実行し続ける必要があるという事実を無視します。

私のNode.jsスクリプト:

var
    Edge = require('Edge');

var foo = Edge.func({
    assemblyFile: 'cs.dll',
    typeName: 'cs.MyClass',
    methodName: 'Foo'
});

// The callback function that will be called from C# code:
function callback(sequence) {
    console.info('Sequence:', sequence);
}

// Register for a callback:
foo({ callback: callback }, true);

// My hack to keep the process alive:
setInterval(function() {}, 60000);

私のC#コード(DLL):

public class MyClass
{
    Func<object, Task<object>> Callback;

    void Bar()
    {
        int sequence = 1;

        while (true)
        {
            Callback(sequence++);
            Thread.Sleep(1000);
        }
    }

    public async Task<object> Foo(dynamic input)
    {
        // Receives the callback function that will be used:
        Callback = (Func<object, Task<object>>)input.callback;

        // Starts a new thread that will call back periodically:
        (new Thread(Bar)).Start();

        return new object { };
    }
}

私が思いついた唯一の解決策は、スケジューラをビジーにしてイベントループが空にならないように空の関数を呼び出すために長い間隔でタイマーを登録し、プロセスが永遠に実行し続けるようにすることでした。

これを私よりもうまくやる方法はありますか?つまり、プロセスを実行し続けるwithoutこの種の「ハック」を使用する必要がありますか?

37
Lucio Paiva

この質問に対する正しい答えはないように見えますが、これまでのところ3つのハックが考えられます。

setInterval(() => {}, 1 << 30);

これにより、約12日ごとに1回起動する間隔が設定されます。

もともと、私のハックはNumber.POSITIVE_INFINITY期間として、タイマーは実際には起動しませんが、この動作は最近変更され、現在、APIは2147483647を超えるものを受け入れません(つまり、2 ** 31 - 1)。ドキュメントを参照してください here および here

参考までに、これまでに示した他の2つの回答を次に示します。

ジョーの:

require('net').createServer().listen();

彼がそれを呼んだように、「偽のリスナー」を作成します。マイナーな欠点は、そのためだけにポートを割り当てることです。

ジェイコブ:

process.stdin.resume();

または同等のもの:

process.stdin.on("data", () => {});

stdinを「古い」モードにします。これは、Node.js v0.10より前に記述されたスクリプトとの互換性のためにNode.jsに引き続き存在する非推奨の機能です( reference )。

18
Lucio Paiva

"old" Streams mode を使用して、決して来ない標準入力をリッスンします。

// Start reading from stdin so we don't exit.
process.stdin.resume();
30
Jacob Krall

別のハックをミックスに追加します。 Promiseを使用して行う方法は次のとおりです。

new Promise(_ => null)

.jsファイルの最後にそれを投げると、永久に実行されるはずです。

1
Micah