web-dev-qa-db-fra.com

Comment empêcher de force un processus Node.js de se terminer?

TL; DR

Quelle est la meilleure façon de forcer un processus Node.js à s'exécuter, c'est-à-dire à empêcher sa boucle d'événements de s'exécuter vide et donc à empêcher le processus de se terminer? La meilleure solution que j'ai pu trouver était la suivante:

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

Ce qui maintiendra un intervalle sans causer trop de perturbations si vous gardez la période d'intervalle assez longtemps.

Y a-t-il une meilleure façon de le faire?

Version longue de la question

J'ai un script Node.js utilisant Edge.js pour enregistrer une fonction de rappel afin qu'elle puisse être appelée à l'intérieur d'un DLL dans .NET. Cette fonction sera appelé 1 fois par seconde, en envoyant un numéro de séquence simple qui devrait être imprimé sur la console.

La partie Edge.js est très bien, tout fonctionne. Mon seul problème est que mon processus Node.js exécute son script et ensuite il manque d'événements à traiter. Avec sa boucle d'événements vide, il se termine simplement, ignorant le fait qu'il aurait dû continuer à fonctionner pour pouvoir recevoir des rappels de la DLL.

Mon script 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);

Mon code C # (la 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 { };
    }
}

La seule solution que j'ai pu trouver était d'enregistrer une minuterie avec un long intervalle pour appeler une fonction vide juste pour garder le planificateur occupé et éviter de vider la boucle d'événements afin que le processus continue de fonctionner indéfiniment.

Y a-t-il un moyen de faire cela mieux que moi? C'est-à-dire, garder le processus en cours sans avoir à utiliser ce type de "hack"?

37
Lucio Paiva

Bien qu'il semble qu'il n'y ait pas de bonne réponse à cette question, jusqu'à présent, nous avons 3 hacks possibles et je pense honnêtement que mon approche est la moins intrusive:

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

Cela définira un intervalle qui se déclenchera environ une fois tous les 12 jours.

À l'origine, mon hack a réussi Number.POSITIVE_INFINITY comme période, de sorte que le minuteur ne se déclencherait jamais, mais ce comportement a récemment été modifié et maintenant l'API n'accepte plus rien de plus de 2147483647 (c'est-à-dire 2 ** 31 - 1). Voir les documents ici et ici .

Pour référence, voici les deux autres réponses données jusqu'à présent:

Joe's:

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

Va créer un "faux auditeur", comme il l'appelait. Un inconvénient mineur est que nous allouerions un port juste pour cela.

Jacob:

process.stdin.resume();

Ou l'équivalent:

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

Met stdin en "ancien" mode, une fonctionnalité obsolète qui est toujours présente dans Node.js pour la compatibilité avec les scripts écrits avant Node.js v0.10 ( référence ).

18
Lucio Paiva

Utilisez "ancien" mode Streams pour écouter une entrée standard qui ne viendra jamais:

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

Je vais lancer un autre hack dans le mix. Voici comment le faire avec Promise

new Promise(_ => null)

Jetez cela au bas de votre .js fichier et il devrait fonctionner pour toujours.

1
Micah