How to restart Hangfire server, or stop it and start a new one, to change the Queues it's processing?
Asked Answered
N

1

9

In my asp.net 5 app I'm using Hangfire to process only certain Queues, based on which tenants the server should be looking after. So at app startup I look up which Queues and start the Hangfire server accordingly.

    public void ConfigureServices(IServiceCollection services)
    {
        // ... do stuff

        services.AddHangfire(config => config
                                .SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
                                .UseSimpleAssemblyNameTypeSerializer()
                                .UseSqlServerStorage(hangfireConnectionString, new SqlServerStorageOptions
                                {
                                    QueuePollInterval = new TimeSpan(0, 0, 0, 0, 500)
                                })
        );

        string[] queueNames = GetQueueNamesForThisServerToProcess();

        services.AddHangfireServer(options =>
        {
            options.Queues = queueNames;
        });

        // ... do more stuff
    }

Sometime later I want to change the Queues that this server is processing. I think I need to just stop this hangfire server and start another one ... but a) how do I get a reference to this one, and b) how should I correctly start a new one, given that the advised method to start a Hangfire server in aspnet core is using services.AddHangfireServer()?

Nitza answered 11/3, 2021 at 12:39 Comment(2)
This docs.hangfire.io/en/latest/background-processing/… could help you.Foremast
Thanks @u1986237, I've read already that but didn't find anything relevant. Was there something specific you saw there?Nitza
W
13

stop a running server

BackgroundProcessingServer can be accessed in any controller after been injected

_server.SendStop();
await _server.WaitForShutdownAsync(new System.Threading.CancellationToken());
_server.Dispose();

start a new server

AddHangfireServer can be triggered accessing an injected IApplicationBuilder

  _applicationBuilder.UseHangfireServer(new BackgroundJobServerOptions
  {
    WorkerCount = 1,
    Queues = new[] { "customqueuename" },
    ServerName = "Custom server 2",
  });

startup.cs

  services.AddSingleton<IBackgroundProcessingServer, BackgroundProcessingServer>();
  services.AddSingleton<IApplicationBuilder, ApplicationBuilder>();

Look here for a complete POC.

Use JobStorage.Current.GetConnection().RemoveTimedOutServers(new TimeSpan(0, 0, 15)); to update /hangfire/servers

Whitehot answered 5/7, 2021 at 18:36 Comment(6)
Thanks @stefan.seeland! I'll try it out when back from vacation but it seemed useful so I awarded the bounty :)Nitza
I am not sure what you mean, the poc is .net5 based -github.com/stesee/HangfireHelloWorld/blob/main/… .Whitehot
I'm not sure either... I'll assemble my thoughts better and rewrite :)Nitza
Sorry, clearly it's .net5. I'm just confused with some things: 1) in Startup I call services.AddHangfireServer() which creates an IHostedService of type BackgroundJobServerHostedService. But in the POC what happens to that? Controller gets a IBackgroundProcessingServer but is that the same one as the BackgroundJobServerHostedService's _processingServer? 2) isn't it weird to use IApplicationBuilder outside the startup process? e.g. when does that builder get built if not in Main()? 3) Calling UseHangfireServer() does slightly different things to AddHangfireServer(), is that ok?Nitza
Can this be done without code, for example making some kind of API call?Previse
In the current version of Hangfire, the IApplicationBuilder.UseHangfireServer() method is deprecated in favor of IServiceCollection.AddHangfireServer() however we can't alter the services after startup.Hip

© 2022 - 2024 — McMap. All rights reserved.