¿Cómo prevenir la ejecución de trabajos recurrentes de Hangfire después de reiniciar IIS? -- # campo con .net campo con hangfire camp Relacionados El problema

How to prevent hangfire recurring job execution after IIS restart?


1
vote

problema

Español

Después de establecer hangfire (v1.7.7) a siempre ejecute , todos los trabajos recurrentes se ejecutan inmediatamente después de reiniciarmos IIS o reciclar la piscina. Es un comportamiento indeseable porque tenemos trabajo programado para ejecutar una vez al mes o una vez a la semana y cada implementación se está haciendo ejecutar.

No pudimos encontrar una propiedad de configuración en la documentación o en los foros para evitar este comportamiento y aún estamos analizando el repositorio, tratando de encontrar una pista.

Encontramos este problema y esta discusión relacionada con nuestro problema. < / p>

Aparte del enlace que se proporciona anteriormente, lo que representa la configuración exacta que hicimos para hacer que la Hangfire siempre funcione, esta es nuestra configuración actual:

  private BackgroundJobServer _backgroundJobServer; app.UseHangfireDashboard("/hangfire", new DashboardOptions {     Authorization = new[] { new HangfireRestrictiveAuthorizationFilter() },     StatsPollingInterval = UM_MINUTO_EM_MILISEGUNDOS * 10 });  GlobalConfiguration.Configuration.UseSqlServerStorage("Implanta", new SqlServerStorageOptions  {      CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),      SchemaName = "HangFireSiscaf",     SlidingInvisibilityTimeout = null });  _backgroundJobServer = new BackgroundJobServer(new BackgroundJobServerOptions() {     Queues = new[] { "siscaf" },     ServerName = "SISCAF.NET",     WorkerCount = 5 });   

y así es como generalmente programamos nuestros trabajos recurrentes (un par de nombres de métodos y cadenas se escriben en PT-BR):

  RecurringJob.AddOrUpdate<ColetaMensalCFATask>(     ColetaMensalCFATask.Key,     x => x.ExecuteTask(),     Cron.Monthly(diaAgendamentoMensalColetaCFA, timeSpanHoraAgendamentoMensalColetaCFA.Minutes),     TimeZoneInfo.Local,     "siscaf");   

Actualizar 1: Pudimos reproducir el comportamiento deseado eliminando el historial de ejecución del trabajo y agregando cada trabajo como uno nuevo. Sin embargo, no una solución satisfactoria.

Original en ingles

After we set Hangfire (v1.7.7) to always run, all recurring jobs execute immediately after we restart IIS or recycle the pool. It's an undesirable behavior because we have jobs scheduled to run once a month or once a week and every deploy is making them run.

We couldn't find a configuration property in the documentation or forums to prevent this behavior and we're still analyzing the repo, trying to find a clue.

We found this issue and this discussion related to our problem.

Apart from the link provided above, which represents the exact configuration we made in order to make Hangfire always run, this is our current configuration:

private BackgroundJobServer _backgroundJobServer; app.UseHangfireDashboard("/hangfire", new DashboardOptions {     Authorization = new[] { new HangfireRestrictiveAuthorizationFilter() },     StatsPollingInterval = UM_MINUTO_EM_MILISEGUNDOS * 10 });  GlobalConfiguration.Configuration.UseSqlServerStorage("Implanta", new SqlServerStorageOptions  {      CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),      SchemaName = "HangFireSiscaf",     SlidingInvisibilityTimeout = null });  _backgroundJobServer = new BackgroundJobServer(new BackgroundJobServerOptions() {     Queues = new[] { "siscaf" },     ServerName = "SISCAF.NET",     WorkerCount = 5 }); 

And this is how we usually schedule our recurring jobs (a couple method names and strings are written in pt-BR):

RecurringJob.AddOrUpdate<ColetaMensalCFATask>(     ColetaMensalCFATask.Key,     x => x.ExecuteTask(),     Cron.Monthly(diaAgendamentoMensalColetaCFA, timeSpanHoraAgendamentoMensalColetaCFA.Minutes),     TimeZoneInfo.Local,     "siscaf"); 

UPDATE 1: We were able to reproduce the desired behavior by deleting the job execution history and adding every job as a new one. Not a satisfying solution though.

        

Lista de respuestas

1
 
vote

Siempre que necesite cambiar el comportamiento dentro de Hangfire, debe escribir una JOBFILTER .

Esta clase puede implementar varias interfaces, pero en su caso, probablemente podría implementar el IClientFilter6 y verifique OnCreating() Si el trabajo debe ser creado o implementar IElectStateFilter y compruebe en OnStateElection() si el trabajo debe ser enqueado.

Tenga en cuenta que ya hay un montón de otros filtros de trabajo y que se ejecutan en un orden definido, dado por el valor entero dentro de la propiedad IClientFilter10 . Para asegurarse de que su filtro sea uno de los últimos, configure esto, tal vez a getItemViewType()1111 .

Para aplicar este filtro de trabajo a su trabajo, puede agregar el atributo al método o la clase o si se debe ejecutar para cada trabajo, puede agregar una instancia a la lista global a través de getItemViewType()212 dentro de su inicio.

Si está dentro de uno de los métodos de filtro, cada uno de ellos tiene una propiedad getItemViewType()313 , que tiene acceso a la API de monitoreo a través del getItemViewType()4 Propiedad:

  getItemViewType()5  

Actualmente no puedo verificar lo que contienen en caso de un trabajo recurrente creado, pero si lo echa un vistazo con el depurador, debe encontrar información sobre el trabajo recurrente. Una forma sencilla de revisar esto, es echar un vistazo al panel de control de suspensión. Si abre la página Detalles del trabajo y busca cualquier cosa que se conecte al trabajo recurrente, que está disponible a través de la API de monitoreo, haga que todas las páginas web de Hangfire usen esta API para obtener su contenido.

Simplemente excavado un poco más y encontró los puntos para recuperar toda la información del trabajo recurrente por un ID de trabajo dado:

  getItemViewType()6  

También el estado enqueuado de un trabajo recurrente siempre tiene como motivo el texto getItemViewType()7 , que se puede usar como filtro como este:

  getItemViewType()8  
 

Whenever you need to change the behaviour within Hangfire you have to write a JobFilter.

This class can implement various interfaces, but in your case you could probably implement the IClientFilter and check in OnCreating() if the job should be created or implement IElectStateFilter and check in OnStateElection() if the job should be enqueued.

Be aware that there are already a bunch of other job filters and that they are executed in a defined order, given by the integer value within the Order property. To ensure that your filter will be one of the last, set this maybe to int.MaxValue.

To apply this job filter to your job, you could either add the attribute to the method or class or if it should be executed for every job you can add an instance to the global list via GlobalJobFilters.Filters.Add() within your startup.

If you are within one of the filter methods, each of them has a context property, that has access to the monitoring api through the Storage property:

var monitor = context.Storage.GetMonitoringApi(); var jobDetails = monitor.JobDetails(context.BackgroundJob.Id);  foreach (var kvp in jobDetails.Properties) {     Trace.WriteLine($"{kvp.Key => kvp.Value}"); }  foreach (var entry in jobDetails.History.OrderBy(e => e.CreatedAt)) {     Trace.WriteLine($"{entry.StateName} ({entry.CreatedAt}): {Reason}");      foreach (var kvp in entry.Data)     {         Trace.WriteLine($"   {kvp.Key} => {kvp.Value}");     } } 

Currently I can't check what they contain in case of a freshly created recurring job, but if you take a look at it with the debugger, you should find some information about the recurring job. One simple way to check this, is to take a look at the Hangfire Dashboard. If you open the job details page and find anything that links to the recurring job, than it is available through the monitoring API, cause all Hangfire Webpages use this API to get their content.

Just dug a little deeper and found the points to retrieve all information from the recurring job by a given job id:

var monitor = context.Storage.GetMonitoringApi(); var jobDetails = monitor.JobDetails(context.BackgroundJob.Id);  if(jobDetails.Properties.TryGetValue("RecurringJobId", out string recurringId)) {     var values = context.Connection.GetAllEntriesFromHash($"recurring-job:{recurringId}");      foreach (var kvp in values)     {         Trace.WriteLine($"{kvp.Key} => {kvp.Value}");     } } 

Also the Enqueued state of a recurring job has always as reason the text Triggered by recurring job scheduler, which can be used as a filter like this:

    public void OnStateElection(ElectStateContext context)     {         switch (context.CandidateState)         {             case EnqueuedState enqueued when enqueued.Reason == "Triggered by recurring job scheduler":                 Trace.WriteLine($"Was triggered by job scheduler.");                  // Skip all jobs of job scheduler                 context.CandidateState = new SucceededState(null, 0, 0);                 break;         }     } 
 
 
 
 

Relacionados problema

2  Hangfire Backgroundjob.enqueue y método serialización  ( Hangfire backgroundjob enqueue and method serialization ) 
con Hangfire Podemos hacer algo así: public MyClass { public void RunJob() { SomeClass x = new SomeClass(); x.SomeProperty = "Test"...

30  ¿Cómo eliminar todos los trabajos recurrentes de Hangfire en el inicio?  ( How to remove all hangfire recurring jobs on startup ) 
Estoy mirando usando Hangfire como programador de empleo para trabajos recurrentes. Por lo tanto, configurarlos es simple con AddOrUpdate , pero luego, ¿cómo...

3  Hang Fire uso de variables dentro de trabajos  ( Hangfire use of variables inside jobs ) 
Sé que Hangfire no se ejecuta en el mismo contexto que ASP.NET y tiene su propio grupo de hilos, pero debería usar variables dentro de mis trabajos de fondo. ...

4  Aclaración de Hangfire en SlidinginVisibilityTimeOut  ( Hangfire clarification on slidinginvisibilitytimeout ) 
El estado de Docs de Hangfire: Una de las principales desventajas de la implementación de almacenamiento de trabajos RAW SQL Server: utiliza la técnica de ...

13  Akka.net Sistema de actor en ASP.NET  ( Akka net actor system in asp net ) 
He creado un servicio con una API RESTFULT en ASP.NET, alojada en IIS. Dentro de este servicio, me gustaría crear un sistema de actor con akka.net. Al crear...

0  ¿Cómo personalizar las tablas de Hangfire?  ( How to customize hangfire tables ) 
Necesito agregar algunas columnas adicionales en las tablas de suspensión. No sé cómo puedo agregar columnas adicionales a las tablas de suspensión. ¿Puede ...

2  Mvc 5 urlhelper sin httpcontext?  ( Mvc 5 urlhelper without httpcontext ) 
Decorar mis acciones MVC 5 con atributos de ruta: [Route("this-test")] public ActionResult ThisTest() y con un httpcontext puedo acceder al nombre de ...

8  Mejores prácticas para Hangfire en Azure  ( Best practices for hangfire on azure ) 
Estoy intentando migrar una solución de ONPREM a Azure. La aplicación utiliza Sangfire bastante pesadamente. Hangfire está alojado en un servicio de Windows y...

4  WEBAPIREQUESTLIFICIO Y FIONSEJOB CONFUSIÓN  ( Webapirequestlifestyle and backgroundjob confusion ) 
Una de mis dependencias (DBContext) se registra utilizando el alcance de WebAPIREQUESTLIFESTYLE. Ahora, mi trabajo de fondo utiliza IOC y depende del servic...

2  Cómo devolver un valor de retorno desde Hangfire  ( How to return a return value from hangfire ) 
noté este campo en el tablero de hangfire para un trabajo sucedido: Me encantaría empujar algunos datos allí, para darme más información sobre lo que hiz...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos