Recurring Job every Seconds

Hi,
is there a plan for a feature that allows of scheduling a Job that run every X second (10sec., 20 sec. etc…) ?

Thanks.

Pietro.

Current implementation recurring job scheduler wakes up every minute, fetches current schedule records, and creates new background jobs based on matched recurring jobs. If we simply change this implementation to wake up every second, we’ll stress our storage with a high number of requests.

To avoid stressing, we can cache schedule records and update them each minute, for example. However, stale records will add a lot of fun cases, and we should think about them first.

On the other hand, I’m planning to implement support for constantly running processes with the following API:

public class MyProcess : IServerComponent
{
    public void Execute(CancellationToken shutdownToken)
    {
        // ...
    }
}

app.UseHangfireServer(new MyProcess()); // or so

So you’ll have an option to define such a constantly running process and use it to create background jobs even every 100 milliseconds. Hangfire already have such an infrastructure, but it is internal now for some reasons. If you are interested, I can show how to extract it to simplify the development.

Hi Sergey,
if it is possible, I’m interested in solution that you have suggested.

Thanks

Regards

Pietro.

After answering you, I’ve thought that you can simply use System.Threading.Timer class in your case. However, for other long-running processes you can take these sources files:

  • IServerComponent – base interface for Hangfire’s long-running processes. ServerWatchdog is the simplest implementation you can look.
  • ServerSupervisor – class that creates a new thread for server component, calls its Execute method in a loop until CancellationToken instance is not canceled.
  • AutomaticRetryServerComponentWrapper – wrapper for IServerComponent to retry Execute method in case of exception with increasing intervals.

Some of this classes are internal yet. The usage is:

class MyComponent : IServerComponent 
{  
    public void Execute(CancellationToken shutdownToken)
    {
        /* Create background jobs, poll queues or whatever */
        shutdownToken.WaitHandle.Wait(TimeSpan.FromSeconds(15));
    }
}

var component = new MyComponent();
var supervisor = new ServerSupervisor(new AutomaticRetryServerComponentWrapper(component));

supervisor.Start();   // Starts supervisor, non-blocking
supervisor.Stop();    // Non-blocking call, calls `CancellationToken.Cancel` method.
supervisor.Dispose(); // Blocking call, waits for `Thread.Join`

You can place them into Application_Start and Application_End methods.

Hello
Now it has been a few years from your posting of this and I still have not seen Hangfire support to run jobs less than 1 minute? I have read several places of several in the community wanting this functionality. But now I have requirements for this and as a longtime user of Hangfire, I would like to use Hangfire for these jobs. So I am wondering if we need to do some customized coding as you proposed above? Or is there something simple that can be done to allow jobs to run every 30 seconds? Our scenario is quite simple, we just need to run very small fast running jobs <1ms every 30 seconds.

I came up with a solution that works for me. I use a scheduler to repeat task under a minute and allow sleep in between. For example, I want every 30 secs. I set the scheduler to run at most 2 times. it does not run second iteration if the first iteration passed the start time for second iteration.

All my tasks follow this format -

public async Task Process(IJobCancellationToken cancellationToken)

Changed to use the scheduler hence body now looks like below where InternalProcess is the old Process.

await _processScheduler.Execute(async () => await InternalProcess(cancellationToken), DateTime.UtcNow.AddMinutes(1), MaxIterations);

Scheduler looks like below

public async Task Execute(Func action, DateTime cutoff, byte maxIterations)
{
/*
* Example: Every 30 seconds
*
* DateTime.UtcNow = 00:00:00
* Cutoff = 00:01:00
* MaxIterations = 2
*
* Interval = 30 seconds
*
*
* Iteration 1:
* Next Start =
* 00:00:30 (if process took less than 30 seconds)
* 00:01:00 (if process took more than 30 secounds) will not run again
*/

        var start = DateTime.UtcNow;
        var interval = (cutoff - start).TotalSeconds / maxIterations;

        for (byte iteration = 1; iteration <= maxIterations && iteration < byte.MaxValue - 1; ++iteration)
        {
            await action();

            var nextStart = start.AddSeconds(iteration * interval);

            while (nextStart <= DateTime.UtcNow && iteration < byte.MaxValue - 1)
            {
                ++iteration;
                nextStart = start.AddSeconds(iteration * interval);
            }

            if (nextStart >= cutoff) break;

            await Task.Delay(nextStart - DateTime.UtcNow);
        }
    }

Hello Sergey,
We are using Hangfire to run our background job; but we want scheduler to constantly get updated jobs from database.
In short, we want recurring scheduler to run every second.

Could you please provide details on this?

Hi Sergey,
We’re checking option to use Hangfire in our product, but we’re need below-the-minute resolution as a must.
As I understood from reading similar articles - it need to upgrade whole internal Hangfire’s infrastructure.
Few questions:

  1. Does this functional exists in PRO version?
  2. I saw you mentioned that this functional will be added in Hangfire 2.* - is this correct? Any timeline?
  3. If you can provide short description how-to-implement it - I can try to implement it by my own and send you a PR. Looks like description from beginning of the topic is obsolete

Please see my answer above

I am also interested in a way to have a permanently running process etc that could do very short schedules or background tasks.