Recurring Jobs: Schedule recurring jobs on start, Change schedule while running, example app

Hi everyone

I’m currently looking into Hangfire to schedule a lot of recurring jobs (cron) with. And I have a couple of questions.

  • What way does everyone use to schedule their jobs when the Web API Hangfire starts? Does everyone just put a ton of RecurringJob.AddOrUpdate in their StartUp?

RecurringJob.AddOrUpdate(“some-id”, () => Console.WriteLine(), Cron.Hourly);

  • Is there any way to change the scheduling of a recurring job while the Web API Hangfire is running?
    – I tried adding a rest contract that accepts a jobid and new cron schedule, but there is no method that can just adjust the cron schedule, I always need a reference to the job?
  • Is there any way I can add jobs to an already running Web API Hangfire, through adding a .dll in a folder somewhere or?

Thank you

Schoof

Seeing as I can’t edit my post (“Body is too similar to what you recently posted”) I will add my edits here.


Hi everyone

I’m currently looking into Hangfire to schedule a lot of recurring jobs (using cron) with. And I have a couple of questions. I will be using the latest version, together with a ASP.NET Core Web API application.

  • What way does everyone use to schedule their jobs when their application starts? Does everyone just put a ton of RecurringJob.AddOrUpdate in their StartUp?
  • Is there any way to change the scheduling of a recurring job while the application is running?
    – I tried adding a rest contract that accepts a jobid and new cron schedule, but there is no method that can just adjust the cron schedule, I always need a reference to the job (this isn’t ideal when you have a lot of jobs)?
  • Is there any way I can add jobs to an already running application like for example through adding a .dll in a folder somewhere?
  • Is there an example application somewhere available that has some advanced scheduling / jobs?

Thank you

A co-worker implemented a Hangfire client into our Hangfire dashboard, so it has a custom page for starting the recurring jobs. It is kinda neat.

Just use the AddOrUpdate method again with the same parameters but another cron string. That will override the existing recurring job. That is why it is called “OrUpdate”.

RecurringJob.AddOrUpdate(sameId, () => Console.WriteLine(), newCronString);

I am not sure what you are asking here. As far as I know you can’t dynamically add code to a .Net program during runtime, but maybe with some blackmagic it is possible. Question is, why would you?

The first issue you will have is that the Hangfire server has to have access to all the needed references of the jobs it runs. The Hangfire dashboard will also be a little pissy if it doesn’t have the needed references, but it will only be display errors and nothing else.

Normally we just deploy a new version of the Hangfire server and Hangfire client at the same time, and it mostly goes over with no issues. Unless you changed something in the code so the jobs that currently enqueued can’t be executed anymore.

Thank you for the reply!

Sounds like a good idea. The current set up I though is that the dashboard, client and server are all in the same ASP.NET Core application, is this not ideal? What would an ideal setup look like?

Yeah and that works, but I have a lot of recurring jobs which I dynamically start at runtime using reflection.

//Remove all recurring jobs from hangfire
            using (var connection = JobStorage.Current.GetConnection())
            {
                foreach (var recurringJob in connection.GetRecurringJobs())
                {
                    RecurringJob.RemoveIfExists(recurringJob.Id);
                }
            }

            //Register recurring jobs
            List<Type> recurringJobTypes = typeof(JobsFactory).Assembly.GetTypes().Where(x => x.BaseType == typeof(BaseRecurringJob)).ToList();

            foreach (Type recurringJobType in recurringJobTypes)
            {
                var recurringJobInstance = (BaseRecurringJob)ActivatorUtilities.CreateInstance(_di, recurringJobType);
                if (recurringJobInstance.Enabled)
                {
                    RecurringJob.AddOrUpdate(recurringJobInstance.JobName, () => recurringJobInstance.Execute(null), recurringJobInstance.Cron);
                }
            }

And then to update the these jobs I would need a reference to every job in my API Controller? For example:

[ApiController]
    public class HangfireController : ControllerBase
    {
        private readonly ILogger<HangfireController> _logger;

        private readonly TestJob _testJob;

        public HangfireController(ILogger<HangfireController> logger, TestJob testJob)
        {
            _logger = logger;
            _testJob = testJob;
        }

        #region Posts

        [HttpPost("api/hangfire/updatejob")]
        public async Task<OkObjectResult> UpdateJob(string jobid, string schedule)
        {
            RecurringJob.AddOrUpdate(jobid, () => _testJob.Execute(null), schedule);

            return Ok("Job updated");
        }

        #endregion
    }

I’m just trying to come up with ideas to make Hangfire work as ideally as I can. :slight_smile:

Yeah you’re right there, that was just wild pipe dream. :stuck_out_tongue:

Thanks again! :slight_smile:

1 Like

My ideal setup would be to have dashboard, servers and clients completely separate. But I can’t have nice things.
See this thread for details and my rant: http://hangfire.discourse.group/t/single-dashboard-single-physical-server-multiple-jobs-projects-codebases-advice-or-examples/3677
I haven’t gotten around to trying the MAMQ workaround extension to get around the Hangfire bug yet.

Otherwise yes you can run all of them in the same project if you want. In my current setup it is all run as two separate projects, the dashboard and the server(s). But the way the clients are setup is a complete mess, that makes me want to hit former co-works with a very big hammer.

If it wasn’t for the ease of deployment of web projects though, I would have made the Hangfire servers run as Windows Services instead. Making the Hangfire servers run on an IIS server is just really annoying and seems to cause me a lot of weird issues. I have learned about Topshelf since though, so I plan to look into it if I ever get time to try the MAMQ workaround extension or the 5 year old Hangfire bug is fixed.