1

I am experiencing a big performance hit with Hangfire running on the same app pool as my web application and our site has become terribly slow with CPU sitting at 96% constantly. I have looked at the Hangfire documentation and there is a way to run hangfire separate as a console or windows service. However, I do not understand how to achieve this and still get the dashboard. I have created a service as described on this link Here. Below is the current setup

Startup

[assembly: OwinStartup(typeof(MyProject.FrontEnd.Startup))]
namespace MyProject.FrontEnd
{
    /// <summary>
    /// 
    /// </summary>
    public class Startup
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="app"></param>
        public void Configuration(IAppBuilder app)
        {
            app.UseHangfireAspNet(GetHangfireServers);
            app.UseHangfireDashboard();

            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
            app.Use<RememberMeTokenMiddleware>();
            .........
        }
private IEnumerable<IDisposable> GetHangfireServers()
        {
            GlobalConfiguration.Configuration
                .SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
                .UseSimpleAssemblyNameTypeSerializer()
                .UseRecommendedSerializerSettings()
                .UseSqlServerStorage("eCertDb");

            yield return new BackgroundJobServer();
        }

If I comment only app.UseHangfireAspNet(GetHangfireServers); the dashboard and application breaks. I get the error

JobStorage.Current property value has not been initialized. You must set it before using Hangfire Client or Server API

. If I comment app.UseHangfireDashboard();, now whereever I have implementation of Hangfire it breaks, e.g. in my business layer

BackgroundJob.Enqueue<DocumentServiceWorker>(_ => _.PublishDocument(application.ApplicationReferenceNo, false));

The problem is how do I still have the above calls in the main application if hangfire is running in a different process? How do I still get the dashboard if I am running Hangfire as a Windows Service, do I need a separate site?

Donald N. Mafa
  • 5,131
  • 10
  • 39
  • 56
  • In the website you shouldn't need to configure a hangfire server, as that's the point of moving it to a service. But to get the dashboard you do correctly have to use .`UseHangfireDashboard()`. Have you configured `.UseSqlServerStorage("connectionString")` in Startup? – Stuart Grassie Nov 09 '22 at 07:42
  • @StuartGrassie Thank you understood, how do I set up the main app as just a client, I have updated the Q to include the GetHangfireServers method, but this yields the BackgroundJobServer? I would like to make this a client then perhaps create a separate site for the Hangfire server – Donald N. Mafa Nov 09 '22 at 08:34
  • Ah, I see your edit. Just don't yield the `BackgroundJobServer`. – Stuart Grassie Nov 09 '22 at 08:36
  • @StuartGrassie I think I am battling there, having removed the yield return new BackgroundJobServer(); it breaks, not sure what the correct syntax is, and all the tutorials only have the singular setup where hangfire runs on the same application – Donald N. Mafa Nov 09 '22 at 10:04

1 Answers1

1

I found a project that essentially answers my question. This is how I changed my code to simply setting the UseSqlServerStorage for the client.

 public class Startup
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="app"></param>
        public void Configuration(IAppBuilder app)
        {
            GlobalConfiguration.Configuration.UseSqlServerStorage("xxxx");
            app.UseHangfireDashboard();

            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
            .......
    }

For the Windows Service I used the provided example from the Hangfire blog.

Example

Donald N. Mafa
  • 5,131
  • 10
  • 39
  • 56