I’ve run into situations where I need to perform actions requested by the client that may take a bit of time. The length of time could be variable and I don’t want to have the client waiting for a response. Let’s take a look at using the Mediator Pattern with Hangfire as a solution to this problem. In a Web API scenario, the request may come in as a PUT or POST from the client. The API would validate the request, send the task to a queue and then return the client a 202 HTTP status code.
Sponsor: Do you build complex software systems? See how NServiceBus makes it easier to design, build, and manage software systems that use message queues to achieve loose coupling. Get started for free.
The request has been accepted for processing, but the processing has not been completed. The request might or might not eventually be acted upon, as it might be disallowed when processing actually takes place. There is no facility for re-sending a status code from an asynchronous operation such as this.This way we can handle the work in another process or thread from the initial request.
Hangfire & MediatRI’ve posted about MediatR before, a nice library that implements the Mediator Pattern for in-process messaging. I use it for both handling both Commands and Queries. For our purposes with Hangfire, it will be used for sending requests that are Commands. I’ve also previously posted about Hangfire, a really great library in .NET for executing background tasks in all types of .NET applications. If you are interested in Hangfire, take a look at this post first. Combining these two libraries allows us to take MediatR out of process and use the same implementation we are used to using in-process.
HelperHangfire provides the ability for your task to be a method on a class. However, the above will not work as there is an issue with serializing the Command. The issue appears to be with MediatR’s Send<Unit> method. Trying to serialize the expression when it contains a type parameter may be the issue. If you are aware of what this specific issue is, please let know in the comments. Since we are using commands that have no return type I just created a static helper function.
SetSerializerSettingsAlso, in order for serialization to be correct we must set the Json.NET TypeNameHandling setting.
Setting to include type information when serializing JSON and read type information so that the create types are created when deserializing JSON.
ExampleSo let’s put this simple example all together. I’m putting the Hangfire server where I’m also creating the task (client). Because of this, I’m printing out which thread is sending the task, as well as which thread the task is executed on. If you were running multiple Hangfire server instances, this would happen on any one of them and allows you to distribute tasks. The resulting output displays that the task was sent from Thread 8 and was executed on Thread 18.
CommentsLet me know if you are using MediatR or the Mediator Pattern with Hangfire and how you have implemented it. Please share in the comments below or on twitter.
Here are some other posts that relate to Hangfire or MediatR that I have written.