Using Hangfire with 1 Web application and multiple databases


#1

Good day everyone,

Before I explain my problem, I want to let you guys now that I’ve already visited this topic with a similar question (https://discuss.hangfire.io/t/how-to-start-multiple-hangfire-servers-1-web-application-multiple-databases/2305) but it doesn’t resolve my concerns.

I’m evaluating Hangfire to see if I can integrate to my solution. So far, I think it has all what I need, however, my solution have these particularities:

  • We use one web page to access multiple databases. When any user visits the web page, They can select which database to connect from a dropdown list, then, the connection string is dinamically created and the main menu is loaded. Any time, the user can log out from that database and select another one.
  • We are using Windows Authentication

Based on theses considerations, I have the following questions which I would like anyone to help me with please:

  • How could I start a Hangfire Server in this scenario? I can’t start the server in Application_Start() event in Global.asax as the documentation suggets, because, at this point, The app doesn’t know yet which database to use. But, if I start the server later, it won’t restart automatically if the pool is restarted and until any user hits the page. Also, If an user creates a task in one database, It should execute at the specified time, no matter if the user is in another database at the time of the event trigger, and so on with the other databases.
  • The previous item makes me think, maybe I have to use a different database only for Hangfire, but, How could the scheduled task knows which DB to run the task on?
  • As we user windows authentication, Which user/context uses hangfire to run the tasks? Maybe I would have to create an user specifically to run tasks using impersonation?
  • Maybe the only solution could be to create a Windows Service and run it separately. But I’m not sure again, about this multiple database handling.

I will be very grateful if anyone can give me some lights about this.


#2
  1. Use a separate database as your hangfire database in production. It does a few things: easier db user segregation, can prevent your application db from getting busy, and makes for easier flexibility in the event you want to have a separate app or service just to access hangfire as it would have a completely different connection string.
  2. In terms of knowing which application db to use, that would have to be something you pass in somehow as these functions shouldn’t assume any state. I wouldn’t recommend passing the actual connection string, but maybe you have aliases for your connections that you can lookup quickly (‘dev’, ‘qa’, ‘prod1’, etc.)
  3. The way I’ve seen how hangfire functions is it just executes under application authority meaning there’s no actual user context or httpcontext present when executing. Any sort of permission level piece needs to be placed on the queuing of the task or based on some data passed into the task. Again, these shouldn’t really assume any statefulness with your data.
  4. You can definitely run the hangfire processing piece as a windows service using a package like TopShelf which essentially lets you write a console app to be deployed and run as a Windows service. It’s possible to have your application only be allowed to queue tasks and have a separate windows service (or pool of them) execute them. This would be particularly useful if you have some cpu intense background jobs and you want your webapp to maintain snappiness as they can be run on separate boxes.

#3

Hi, Thank you very much for your response. I’ll take your advice and I’ll make some tests. I didn’t know about Topshelf, so, also I’ll spend some time with it.