This is a pre-release version that adds a lot of great new features for Hangfire requested by you, including background processes, built-in support for custom scopes in IoC containers, queues for recurring jobs and much more!

Code snippets were updated for Hangfire 1.5.0 release.

Background Processes

Background process is a continuously-running process that starts with Hangfire Server and operates during all its lifetime. It is like a custom background thread (it is really based on a thread), but powered with automatic retries and logging in case of unexpected exceptions.

Background processes were formerly known as server components in previous versions of Hangfire. And they already doing a lot of work for you, since workers, recurring job schedulers and other internal classes are based on these interfaces. Since this release it is now possible to define custom processes.

public class CleanTempDirectoryProcess : IBackgroundProcess
{
    public void Execute(BackgroundProcessContext context)
    {
        // Pseudocode
        Directory.CleanUp(Directory.GetTempDirectory());
        
        // Wait for an hour before next attempt
        context.Wait(TimeSpan.FromHours(1));
    }
}

Background process’s Execute method is called in a loop. When the code throws an exception, it will be logged, and the next attempt will be made after an increasing delay interval. To include a new background job process, just use the new overloads for the UseHangfireServer method and BackgroundJobServer constructor.

app.UseHangfireServer(new CleanTempDirectoryProcess());

IoC Container Scopes

Sometimes you need to register a shared instance of a service in IoC container whose lifecycle will be equal to the background job processing – unit of works, database connection, transaction, etc. Previously you had to search in a forum how to do this and install custom job filter.

Since this version, custom scopes for IoC containers are integrated into the core. This is the registration of a shared component in Hangfire.Autofac:

var builder = new ContainerBuilder();
builder.RegisterType<Database>()
    .InstancePerBackgroundJob()
    .InstancePerHttpRequest();

GlobalConfiguration.Configuration.UseAutofacActivator(builder.Build());

And this is for Hangfire.Ninject:

var kernel = new StandardKernel();
kernel.Bind<Database>().ToSelf().InRequestOrBackgroundJobScope();

GlobalConfiguration.Configuration.UseNinjectActivator(kernel);

Disposable instances will be disposed just after the processing. However, please refer to the corresponding IoC container integration documentation as there are some caveats.

Instant Re-Queue for SQL Server

Say goodbye to confusing invisibility timeout with unexpected background job retries after 30 minutes (by default) when using SQL Server. New Hangfire.SqlServer implementation uses plain old transactions to fetch background jobs and hide them from other workers.

Even after ungraceful shutdown, the job will be available for other workers instantly, without any delays.

Queues for Recurring Jobs

Want to run recurring jobs on a per-machine basis? You don’t longer need to reinvent how to do this using filters – there is a new queue parameter for the AddOrUpdate method that allows you to choose a queue. But please remember that QueueAttribute may override it as well as other filters that modify the Enqueued state.

RecurringJob.AddOrUpdate(
    () => Console.WriteLine(Environment.MachineName), 
    Cron.Daily, 
    queue: Environment.MachineName);

Remote Queues Support for MSMQ

Well, this was very strange that remote MSMQ queues were not supported in Hangfire in previous versions. Starting from now, it is possible when using MSDTC transactions with the following path format:

GlobalConfiguration.Configuration
    .UseSqlServerStorage(@"Server=.\sqlexpress;Database=Hangfire.Sample;Trusted_Connection=True;")
    .UseMsmqQueues(MsmqTransactionType.Dtc, @"FormatName:DIRECT=OS:server\hangfire-{0}", "default", "critical");

Please note that configuration is a bit complex in this case, and you should enable MSDTC service, enable network access to MSDTC and enable inbound/outbound rules for MSDTC in your firewall.

More Options for Background Job Server

New properties in BackgroundJobServerOptions enable you to customize the core processes in background processing   use separate filters or job activators for different server instances, or define your own creation/performance processes.

Here is an example of how to pass custom filter without touching the global collection:

// JobFilterProviders.Providers allows to use predefined filter collections
var providers = new JobFilterProviderCollection(JobFilterProviders.Providers);
var filters = new JobFilterCollection();

filters.Add(new CustomFilter());
providers.Add(filters);

var options = new BackgroundJobServerOptions
{
    FilterProvider = providers,
    Activator = new NinjectJobActivator(kernel)
};

app.UseHangfireServer(options);

Custom Background Servers

And last, but not least   you can de-composite the BackgroundJobServer and use the only background processes you need. BackgroundProcessingServer (without the job word) enables you to create a custom processing server from the ground up.

Want 3 workers listening the default queue and 7 listening the critical queue? No problem. Don’t want to use recurring job scheduler on some instances? You can do this! Just pass the processes you need:

var processes = new List<IBackgroundProcess>
{
    new Worker("default"),
    new DelayedJobScheduler(),
    new RecurringJobScheduler()
};

using (var server = new BackgroundProcessingServer(processes))
{
    Console.WriteLine("Custom BackgroundServer started. Press ENTER to exit...");
    Console.ReadLine();
}

Subscribe to monthly updates

Subscribe to receive monthly blog updates. Very low traffic, you are able to unsubscribe at any time.

Comments