node.js: setInterval () ignore les appels

Pour un projet à venir avec node.js j'ai besoin pour effectuer diverses tâches d'entretien périodiques fois. Plus précisément certaines tâches à chaque milliseconde, d'autres toutes les 20 ms (50 fois par seconde) et d'autres encore à chaque seconde. J'ai donc pensé à utiliser la fonction setInterval(), avec des drôles de résultats: de nombreux appels de fonction ont été ignorées.

La référence que j'ai utilisé est comme suit:

var counter = 0;
var seconds = 0;
var short = 1;
setInterval(function() {
        counter ++;
    }, short);
setInterval(function() {
        seconds ++;
        log('Seconds: ' + seconds + ', counter: ' +
             counter + ', missed ' +
             (seconds * 1000 / short - counter));
    }, 1000);

Il y a un timer long d'un deuxième et d'un court qui peut être ajusté à l'aide de la variable shortdans ce cas, 1 ms. Chaque seconde nous imprimer la différence entre le nombre de tiques dans le cycle court et le nombre de fois que le court compteur a été mis à jour.

Ici est de savoir comment il se comporte quand le timer court est de 1 ms:

2012-09-14T23:03:32.780Z Seconds: 1, counter: 869, missed 131
2012-09-14T23:03:33.780Z Seconds: 2, counter: 1803, missed 197
2012-09-14T23:03:34.781Z Seconds: 3, counter: 2736, missed 264
...
2012-09-14T23:03:41.783Z Seconds: 10, counter: 9267, missed 733

De nombreux appels de fonction sont ignorés. Ici, il est de 10 ms:

2012-09-14T23:01:56.363Z Seconds: 1, counter: 93, missed 7
2012-09-14T23:01:57.363Z Seconds: 2, counter: 192, missed 8
2012-09-14T23:01:58.364Z Seconds: 3, counter: 291, missed 9
...
2012-09-14T23:02:05.364Z Seconds: 10, counter: 986, missed 14

Mieux, mais à peu près un appel de fonction est ignorée à chaque seconde. Et pour les 20 ms:

2012-09-14T23:07:18.713Z Seconds: 1, counter: 46, missed 4
2012-09-14T23:07:19.713Z Seconds: 2, counter: 96, missed 4
2012-09-14T23:07:20.712Z Seconds: 3, counter: 146, missed 4
...
2012-09-14T23:07:27.714Z Seconds: 10, counter: 495, missed 5

Enfin pour 100 ms:

2012-09-14T23:04:25.804Z Seconds: 1, counter: 9, missed 1
2012-09-14T23:04:26.803Z Seconds: 2, counter: 19, missed 1
2012-09-14T23:04:27.804Z Seconds: 3, counter: 29, missed 1
...
2012-09-14T23:04:34.805Z Seconds: 10, counter: 99, missed 1

Dans ce cas, il saute très peu d'appels (l'écart est passé à 2, après 33 secondes et 3 après 108 secondes.

Les chiffres varient, mais sont étonnamment cohérente entre les pistes: l'Exécution de la première 1 ms référence à trois reprises donné un délai au bout de 10 secondes de 9267, 9259 et 9253.

Je n'ai pas trouvé de références pour ce problème particulier. Il y a cette beaucoup cité Ressig post et beaucoup de JavaScript liées à des questions, mais la plupart supposent que le code s'exécute dans un navigateur et non dans node.js.

Maintenant, pour la terrible question: ce qui se passe ici? Juste plaisanter; il est évident que les appels de fonction sont ignorés. Mais je n'arrive pas à voir le modèle. Je pensais que les cycles longs qui pourrait empêcher les courts, mais il n'a pas de sens dans le 1 cas de sp. Cycle court des appels de fonction sont chevauchent pas puisqu'ils ont juste de mettre à jour une variable, et la node.js le processus est de près de 5% de CPU, même avec un cycle court de 1 ms. La charge moyenne est élevée, même si, à environ 0.50. Je ne sais pas pourquoi d'un millier d'appels sont en insistant sur mon système autant, bien que, depuis node.js poignées beaucoup plus de clients parfaitement; il doit être vrai que setInterval() est l'UC (ou je fais quelque chose de mal).

Une solution évidente est de regrouper les appels de fonction à l'aide de plus longues, et puis exécutez le cycle court des appels de fonction plusieurs fois pour simuler une courte minuterie. Ensuite, utilisez le cycle long comme une "voiture-balai", qui rend tout d'appels manqués dans la partie inférieure des intervalles. Un exemple: 20 ms et 1000 ms setInterval() appelle. Pour 1 ms appels: appeler 20 fois dans les 20 ms de rappel. Pour les 1000 ms appel: vérifier combien de fois les 20ms fonction a été appelée (p. 47), n'importe quel restant appels (par exemple 3). Mais ce schéma va être un peu complexe, car les appels peuvent se chevaucher de manière intéressante, aussi il ne sera pas régulière, bien qu'il puisse ressembler.

La vraie question est: peut-il être fait mieux, avec setInterval() ou d'autres minuteurs dans les node.js? Merci à l'avance.

source d'informationauteur alexfernandez