I am implementing Hangfire in our solution and we are using a build and application server.
That gives us a lot of versions for the same application, that all run against one DB. So all the jobservers will race to fetch the job when it is created, without knowing if they have the correct code to execute the job.
I would like the servers to only fetch jobs for that version.
Add a column “Version” to the Job and Server table to identify a specific version of the application. When the Server is created that version is applied and the same goes for a job creation. If the server has a value in “Version” it only fetches jobs with that version.
You might also just use the servername from the Server table since this should be unique, but then you would need a BackgroundJobServerOptions.UseApplicationVersioning flag. You would also need to add a Job.ServerName column
Please disregard the alternative:
A JobserverName will get an application Id at the end eg. “:9015” which can change after a IIS og PC reset.
Why is this even a problem:
One might argue why we are not just overwriting the last build or have a DB for each version. Our testresources and consultants test a specific version and this makes sure it wont crash and get owerwritten by bad stuff. We have a lot of different customers with different DB for their testdata, so spawning a DB for each customer and each version would mean massive overload for the DB server.
Sorry to revive an old topic, but I do have the same requirement - although not for the same reason.
We have an application running on several servers for load balancing / failover purposes.
All of these servers would have at least one instance of a Hangfire server running but all pointing to the same database because they are meant to process the same jobs.
When we install a new software release, we don’t install it on all servers simultaneously, but first on one, have it running for a while and if everything’s ok, we install the software on the other servers as well.
To prevent issues arising from different versions not working together, we have implemented a versioning system so only compatible components will interact.
I think the solution proposed by AndersRisager would satisfy our needs perfectly (maybe with the addition of being able to say: this server can cope with versions up to X, instead of only versions exactly matching X).
Are there any plans for adding such a functionality?
Otherwise, we would need to introduce ‘versioned’ queues, but depending on the number of queues involved, that’s not very practical…
@dusty, you can use versioned interfaces to handle your issues. You can start with IBackgroundJobsV1 and create a new interface (IBackgroundJobsV2) every time the logic changes. So your new application will be able to route V1 jobs to old logic, V2 jobs to the new logic, etc.
You can also use elect state filter to catch failed jobs due to absence of the IBackgroundJobV2 interface in old application instance, and change the candidate state to EnqueuedState for cases, where old app can’t handle a new background job.
Using versioned interfaces would still result in exceptions when a BackgroundJobServer not knowing the new version picks up the job - versioned queues (JobQueueV1, JobQueueV2) on the other hand should prevent BackgroundJobServers from looking at the new queue which contains jobs they don’t understand.
The cleanest solutions would IMHO still be to introduce versioning of jobs and servers.
For the time being, I’m working with versioned queues, so new Jobs will be sent to a new version of the queue and only the BackgroundJobServer installed with the corresponding code will be configured to look at the new queue.