J'ai un travail très récurrent qui utilise DisableConcurrentExecution(timeout:0)
(0 tentatives), car un seul travailleur devrait le traiter à un moment donné, surtout si le travail prend plus d'une minute (cela varie).
Je ne veux pas que les tâches "sautées" soient signalées comme failed
sur le tableau de bord, donc je voulais ajouter un SkipConcurrentExecutionAttribute
qui serait presque identique à DisableConcurrentExecutionAttribute
, sauf qu'il essaierait/attraperait l'acquisition du verrou, et avalerait DistributedLockTimeoutException
et définirait le travail sur DeletedState
avec la raison.
Mais je ne peux pas le faire correctement, car GetResource() est privé et son implémentation fait référence à d'autres méthodes internes à la bibliothèque.
$"{job.Type.ToGenericTypeString()}.{job.Method.Name}"
semble être le moyen sûr de produire des noms de verrous distribués non conflictuels, mais je ne peux pas m'y référer.
Pouvons-nous avoir dans la lib une méthode publique qui génère le nom de verrou distribué du travail ?
cf., https://discuss.hangfire.io/t/disableconcurentexecution-for-job-groups/1389/4
Je viens de remarquer que filterContext.BackgroundJob.Job.ToString()
donnerait la même chaîne que les (ré)implémentations internes de TypeExtensions.cs et DisableConcurrentExecutionAttribute.cs... problème résolu.
@dgaspar , vous pouvez dire au planificateur de tâches récurrentes d'ignorer la création de la prochaine tâche récurrente, lorsque la précédente est toujours en cours d'exécution, veuillez consulter cet aperçu : https://gist.github.com/odinserj/a6ad7ba6686076c9b9b2e03fcf6bf74e.
Merci pour la suggestion @odinserj. J'ai remarqué que si le travailleur se bloque pendant l'exécution, cette ligne "En cours d'exécution" restera dans la table de hachage. Cela empêchera-t-il la replanification du travail jusqu'à ce que je supprime manuellement cette ligne ? Ou y a-t-il une date d'expiration/nettoyage qui me manque ? (au fait, j'utilise new SqlServerStorageOptions { SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5) }
, si cela compte)
Lorsqu'un travailleur est terminé pendant l'exécution d'une tâche en arrière-plan, cette tâche en arrière-plan sera replanifiée automatiquement, car toutes les files d'attente de messages sont transactionnelles (au moins les files d'attente officielles, les autres implémentations de stockage doivent agir de la même manière).
Commentaire le plus utile
@dgaspar , vous pouvez dire au planificateur de tâches récurrentes d'ignorer la création de la prochaine tâche récurrente, lorsque la précédente est toujours en cours d'exécution, veuillez consulter cet aperçu : https://gist.github.com/odinserj/a6ad7ba6686076c9b9b2e03fcf6bf74e.