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.
In my previous post, I created a few extension methods for Hangfire and MediatR in order to enqueue an IRequest. However, it was not following Hangfire Best Practice. The purpose was to have the IRequest serialized entirely when calling Enqueue(), which would be stored in Hangfires storage. Then when the request would be invoked, Hangfire would deserialize the IRequest and call Mediators Send(). My functioning example worked as expected. However, Hangfire recommends making your job arguments small and simple.Best Practice
Method invocation (i.e. a job) is serialized during the background job creation process. Arguments are converted into JSON strings using the TypeConverter class. If you have complex entities and/or large objects; including arrays, it is better to place them into a database, and then pass only their identities to the background job. Instead of doing this:Consider doing this:public void Method(Entity entity) { }
public void Method(int entityId) { }
New Process
I liked my initial approach using extension methods and using the Hangfire’s JobActivator in order to construct the class that will be sending the Request to MediatR. Using the best practice the changes needed would be:- Pass a database connection factory to the Hangfire Configuration extension method (UseMediatr)
- Create a new MediatR extension method to pass a CommandId and the Request
- Insert a new record into a database with the CommandId and serialized Request
- Create a new method that will be invoked by Hangfire when only using the Command
- Select the record out of the database and deserialize the Request
- Send to MediatR
I ended up using this approach by default because Hangfire replaced a home grown background processing engine that was using times and a database table. All I had to do to switch was start queuing up the Ids in Hangfire and turn off the other process’s timer. So I guess that is a kind of advantage, Hangfire becomes just an implementation detail and can be easily replaced later if need be. BTW: Hangfire has been working flawlessly with Redis for months now, I pretty much keep forgetting it’s there 🙂
Great to hear about Redis! Likely going to be switching to it sooner rather than later as well.