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!
- Background Processes
- IoC Container Scopes
- Instant Re-Queue for SQL Server
- Queues for Recurring Jobs
- Remote Queues Support for MSMQ
- More Options for Background Job Server
- Custom Background Servers
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(); }