Saltar al contenido

Tareas recurrentes de Hangfire por debajo de un minuto

Contamos con la contestación a este contratiempo, al menos eso pensamos. Si presentas dudas puedes dejarlo en el apartado de comentarios, que con placer te ayudaremos

Solución:

No estoy seguro de cuándo se admitió esto, pero lo probé en ASP.NET Core 2.0 con Hangfire 1.7.0. El siguiente código programa un trabajo cada 20 segundos:

RecurringJob.AddOrUpdate(
    x => x.DoWork(),
    "*/20 * * * * *");

Si no me equivoco, se admiten 6 tokens (a diferencia de los 5 tokens estándar) debido al uso de Hangfire de NCrontab, que permite expresiones cron con 6 tokens (segundo granularidad en lugar de minuto granularidad).

El tablero de Hangfire también muestra muy bien el pequeño intervalo de tiempo entre ejecuciones:

Tablero de Hangfire

Creo que cualquiera que esté en contra de permitir un disparo recurrente de menos de 1 minuto es miope. Después de todo, ¿55 segundos son menos eficientes que 1 minuto? ¡Parece tan arbitrario! Por mucho que ame Hangfire, me he encontrado con situaciones en las que tuve que dirigir a un cliente a Quartz.net simplemente porque había un requisito comercial para que un trabajo se ejecutara cada 55 segundos o similar.

Cualquiera que argumente en contra de que si se configuró para ejecutarse cada 1 segundo, tendría un impacto serio en el rendimiento, nuevamente está tomando una visión cerrada de las cosas. Por supuesto, un disparador con un intervalo de 1 segundo probablemente no sea una buena idea, pero ¿rechazamos 55 segundos o 45 segundos para la improbable situación en la que alguien elegirá 1 segundo?

En cualquier caso, el rendimiento es tanto subjetivo como dependiente de la plataforma y el hardware del host. Realmente no depende de la API hacer cumplir la opinión cuando se trata de rendimiento. Simplemente haga que el intervalo de sondeo y la recurrencia del desencadenador sean configurables. De esa manera, el usuario puede determinar el mejor resultado por sí mismo.

Aunque un proceso en segundo plano que orqueste un trabajo para que se ejecute cada 55 segundos puede ser una opción, no es muy satisfactorio. En este caso, el proceso no es visible a través de la interfaz de usuario de Hangfire, por lo que está oculto para el administrador. Siento que este enfoque está eludiendo uno de los principales beneficios de Hangfire.

Si Hangfire fuera un competidor serio como Quartz.net, al menos coincidiría con su funcionalidad básica. Si Quartz puede admitir disparadores con un intervalo inferior a 1 minuto, ¿por qué no Hangfire?

Aunque Hangfire no le permite programar tareas por menos de un minuto, en realidad puede lograr esto haciendo que la función se programe recursivamente; es decir, supongamos que desea que se active algún método cada 2 segundos; puede programar un trabajo en segundo plano que llame al método en el inicio;

BackgroundJob.Schedule(() => PublishMessage(), TimeSpan.FromMilliseconds(2000));

Y luego, en su método PublishMessage, haga sus cosas y luego programe un trabajo para llamar al mismo método;

public void PublishMessage()
    
        /* do your stuff */

        //then schedule a job to exec the same method
        BackgroundJob.Schedule(() => PublishMessage(), TimeSpan.FromMilliseconds(2000));
    

La otra cosa que debe anular es el SchedulePollingInterval predeterminado de 15 segundos; de lo contrario, su método solo se activará después de cada 15 segundos. Para hacerlo, simplemente pase una instancia de BackgroundJobServerOptions a UseHangfireServer en su inicio, así;

var options = new BackgroundJobServerOptions
        
            SchedulePollingInterval = TimeSpan.FromMilliseconds(2000)
        ;

        app.UseHangfireServer(options);

No sé cuán “infalible” es mi solución, pero logré lograr mi objetivo con ella y todo está “feliz” en producción.

Valoraciones y comentarios

Si te animas, puedes dejar un ensayo acerca de qué le añadirías a este ensayo.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *