2017-07-03 1 views
-1

J'ai actuellement un serveur 'cron' en cours d'exécution. Il est supposé exécuter toutes les commandes temporisées qui doivent être exécutées dans le futur. C'est la seule chose que fait le serveur. Ce qui fonctionne: Exécution des fonctions sur mon propre ordinateur portable, tout est exécuté dans le temps.Le serveur Cron est retardé de plusieurs minutes en utilisant setTimeout()

Qu'est-ce qui est cassé: Exécution des fonctions sur plusieurs jours sur le serveur.

Mon code est tout placé dans un projet express (Node) afin que les appels peuvent être effectués par d'autres serveurs pour ajouter plus « crons »

mise en page du dossier:

app.js 
-api/ 
--crons/ 
---router.js 
---functions.js 
--.../ 

Dans les fonctions fichier mes fonctions pour ajouter un cron et l'exécuter sont conservés.

const _ = require('lodash'); 
const Crons = []; 
const moment = require('moment'); 

const functions = { 

addCron: (toExecute, dateTime, id, name) => { 
    console.log('Cron', dateTime, name, id); 
    const now = new Date().getTime(); 
    const then = new Date(dateTime).getTime(); 
    const diff = Math.max(then - now, 0); 

    let cronJob; 
    if (diff >= Math.pow(2, 31)) { 
     if(functions.get(name)) { 

     } 
     cronJob = setTimeout(() => { 
     functions.remove(name); 
     functions.addCron(toExecute, dateTime, id, name); 
     }, diff); 
     Crons.push({ 
     name: name, 
     job: cronJob 
     }); 
    } else { 
     if(functions.get(name)) { 
     functions.remove(name); 
     } 
     cronJob = setTimeout(() => { 
     console.log(`Started cron: ${name} at ${new Date()}`); 
     toExecute(id); 
     functions.remove(name); 
     }, diff); 
     Crons.push({ 
     name: name, 
     job: cronJob 
     }); 
    } 

    } 
}; 

module.exports = functions; 

Actuellement mes journaux quand je lance cela me montrent localement que toutes les fonctions sont exécutées environ 1 milliseconde trop tard (ce qui est bien). Et les journaux sur le serveur en direct me montrent que les fonctions sont beign courir 7 minutes plus tard chaque jour.

Les journaux

1|cronserver | 2017-06-30 18:00:07.195000000: Cron 2017-07-01T17:00:00.000Z YQkWN6BmX8eqzQHC9startCheck YQkWN6BmX8eqzQHC9 
1|cronserver | 2017-06-30 18:00:07.195000000: Cron 2017-07-01T17:30:00.000Z 7c2yPyfjKDuujKQjhstartCheck 7c2yPyfjKDuujKQjh 
1|cronserver | 2017-06-30 18:00:07.196000000: Cron 2017-07-02T17:00:00.000Z PQKoboRpSkWeTufSdstartCheck PQKoboRpSkWeTufSd 
1|cronserver | 2017-06-30 18:00:07.196000000: Cron 2017-07-02T17:30:00.000Z yLFaAjACB9uNPd4YvstartCheck yLFaAjACB9uNPd4Yv 
1|cronserver | 2017-06-30 18:00:07.199000000: Cron 2017-07-01T17:30:00.000Z YQkWN6BmX8eqzQHC9start YQkWN6BmX8eqzQHC9 
1|cronserver | 2017-06-30 18:00:07.199000000: Cron 2017-07-01T18:00:00.000Z 7c2yPyfjKDuujKQjhstart 7c2yPyfjKDuujKQjh 
1|cronserver | 2017-06-30 18:00:07.199000000: Cron 2017-07-02T17:30:00.000Z PQKoboRpSkWeTufSdstart PQKoboRpSkWeTufSd 
1|cronserver | 2017-06-30 18:00:07.199000000: Cron 2017-07-02T18:00:00.000Z yLFaAjACB9uNPd4Yvstart yLFaAjACB9uNPd4Yv 
1|cronserver | 2017-07-01 17:07:32.253000000: Started cron: YQkWN6BmX8eqzQHC9startCheck at Sat Jul 01 2017 17:07:32 GMT+0000 (UTC) 
1|cronserver | 2017-07-01 17:37:33.160000000: Started cron: 7c2yPyfjKDuujKQjhstartCheck at Sat Jul 01 2017 17:37:33 GMT+0000 (UTC) 
1|cronserver | 2017-07-01 17:37:33.161000000: Started cron: YQkWN6BmX8eqzQHC9start at Sat Jul 01 2017 17:37:33 GMT+0000 (UTC) 
1|cronserver | 2017-07-01 18:07:34.070000000: Started cron: 7c2yPyfjKDuujKQjhstart at Sat Jul 01 2017 18:07:34 GMT+0000 (UTC) 
1|cronserver | 2017-07-02 17:14:24.678000000: Started cron: PQKoboRpSkWeTufSdstartCheck at Sun Jul 02 2017 17:14:24 GMT+0000 (UTC) 
1|cronserver | 2017-07-02 17:44:25.587000000: Started cron: yLFaAjACB9uNPd4YvstartCheck at Sun Jul 02 2017 17:44:25 GMT+0000 (UTC) 
1|cronserver | 2017-07-02 17:44:25.588000000: Started cron: PQKoboRpSkWeTufSdstart at Sun Jul 02 2017 17:44:25 GMT+0000 (UTC) 
1|cronserver | 2017-07-02 18:14:26.496000000: Started cron: yLFaAjACB9uNPd4Yvstart at Sun Jul 02 2017 18:14:26 GMT+0000 (UTC) 

La seule chose que ce serveur n'exécute ces fonctions. Toute aide serait grandement appréciée. TL; DR Mes fonctions setTimout sont en retard. Comment puis-je résoudre ce problème

+0

Utilisez-vous node.js? – pokeybit

+0

Oui, je le fais, je l'ajoute en tant que balise maintenant. – mitchken

+0

qu'est ce que 'functions.remove'? Etes-vous en train de nettoyer les "Crons"? Votre code actuel l'augmente sans limite: il ralentit progressivement tout ... – dfogni

Répondre

1

setTimeoutsetTimeout seulement est exécuté une fois, donc je ne considérerais pas cela comme un "travail cron", mais plutôt un travail que vous souhaitez exécuter une fois dans le futur. Laissant cela de côté, setTimeout n'est pas censé être exact et il y a multiple known reasons why your setTimeout timer executes at the wrong time. comment fonctionne setTimeout est qu'il crée un événement dans la file d'attente d'événements et ce n'est pas jusqu'à ce que la file d'attente libère qu'il exécute votre code, as explained here. Je pourrais facilement voir une situation où si vous avez plusieurs fonctions setTimeout en cours d'exécution, cela entraînera des retards lors de leur exécution. Ou plus probablement vous avez un autre problème de fuite de mémoire, qui bouillonne ici. Peu importe, il existe de nombreuses autres options pour accomplir ce que vous essayez de faire. J'ai utilisé node-cron pour des emplois cron réels et c'est assez mignon. Il existe également plusieurs façons d'exécuter des tâches uniques dans leurs propres files d'attente, par exemple Kue ou RabbitMQ.

+0

Le noeud cron n'utilise-t-il pas setTimeout dans ses propres fonctions? Alors, comment peuvent-ils être plus précis? – mitchken

+0

Voici des discussions assez similaires https://github.com/kelektiv/node-cron/issues/218 et https://github.com/node-schedule/node-schedule/issues/368 - Ils discutent en cours d'exécution des milliers de setTimeout à la fois avec un minimum de retards. Le plus probable dans le code exécuté est l'exécution du code de synchronisation qui obstrue la boucle d'événements. Je suggérerais d'avoir votre travail cron et le code qui s'exécute en cours d'exécution sur différents processus. – jjbskir