Eu tenho um trabalho recorrente minucioso que usa DisableConcurrentExecution(timeout:0)
(0 tentativas), pois apenas um trabalhador deve processá-lo em um determinado momento, especialmente se o trabalho levar mais de um minuto para ser concluído (varia).
Não quero que as tarefas "puladas" sejam sinalizadas como failed
no painel, então queria adicionar SkipConcurrentExecutionAttribute
que seria quase idêntico a DisableConcurrentExecutionAttribute
, exceto que tentaria / travaria a aquisição do bloqueio e engoliria DistributedLockTimeoutException
e definiria o trabalho para DeletedState
com o motivo.
Mas não posso fazer isso corretamente, porque GetResource () é privado e sua implementação se refere a outros métodos internos à biblioteca.
$"{job.Type.ToGenericTypeString()}.{job.Method.Name}"
parece ser a maneira segura de produzir nomes de bloqueio distribuído não conflitantes, mas não posso me referir a ele.
Podemos ter na biblioteca um método público que gere o nome de bloqueio distribuído da tarefa?
cf., https://discuss.hangfire.io/t/disableconcurentexecution-for-job-groups/1389/4
Acabei de notar que filterContext.BackgroundJob.Job.ToString()
forneceria a mesma string que o TypeExtensions.cs interno e DisableConcurrentExecutionAttribute.cs (re) implementações ... problema resolvido.
@dgaspar , você pode dizer ao agendador de trabalho recorrente para pular a criação do próximo trabalho recorrente, quando o anterior ainda estiver em execução, consulte esta essência: https://gist.github.com/odinserj/a6ad7ba6686076c9b9b2e03fcf6bf74e.
Obrigado pela sugestão @odinserj. Percebi que se o trabalhador travar durante a execução, a linha "Running" permanecerá na tabela de Hash. Isso impedirá que o trabalho seja reprogramado até que eu exclua manualmente essa linha? Ou há uma expiração / limpeza que estou perdendo? (aliás, estou usando new SqlServerStorageOptions { SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5) }
, se isso importa)
Quando um trabalhador é encerrado durante a execução de um trabalho em segundo plano, esse trabalho em segundo plano será reprogramado automaticamente, porque todas as filas de mensagens são transacionais (pelo menos as oficiais, outras implementações de armazenamento devem agir da mesma maneira).
Comentários muito úteis
@dgaspar , você pode dizer ao agendador de trabalho recorrente para pular a criação do próximo trabalho recorrente, quando o anterior ainda estiver em execução, consulte esta essência: https://gist.github.com/odinserj/a6ad7ba6686076c9b9b2e03fcf6bf74e.