Check if HangFire.JobStorage is instantiated
Asked Answered
S

2

12

I have a ASP.NET MVC Application that works as Hangfire client - it enqueues different jobs. I am using SqlServerJobStorage for Hangfire usage.

For now i am working on a scenario when there is no connection to Hangfire Database, and somewhere in the future connection is being instantiated.

The goal is that my ASP.NET MVC Application should keep working before this moment. After connection restores it should start to enqueue jobs.

So application will throw an exception in Global.asax:

Hangfire.GlobalConfiguration.Configuration.UseSqlServerStorage("EshopServiceHangfire");

Moreover all job enqueues will also throw exceptions:

 BackgroundJob.Enqueue<ISomeClass>(x => x.DoSomethingGreat(JobCancellationToken.Null));

I put the row from Global.asax in a try/catch block, so it will not throw. When somebody enqueue job, i want to check JobStorage.Current and if it is not initialized, i`l try to init it again with the same code:

Hangfire.GlobalConfiguration.Configuration.UseSqlServerStorage("EshopServiceHangfire");

Does anybody knows a way to do this? Documentation has no information about this.

Something like Hangfire.GlobalConfiguration.JobStorage.IsInitialized ?

Catching exception from Job enqueue also is a way, but i don`t like it, because it throws non specific

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

Much appreciated for those who have read up to this place)

Shrive answered 6/6, 2017 at 9:38 Comment(0)
Z
10

You could use the Hangfire.JobStorage.Current static property itself to check Hangfire storage configuration:

//InvalidOperationException " JobStorage.Current property value has not been initialized"
var storage = JobStorage.Current;

GlobalConfiguration.Configuration.UsePostgreSqlStorage(vaildConnString);

//no exception
storage = JobStorage.Current;

Moreover, you could query a database to test the connection:

JobStorage.Current.GetConnection().GetRecurringJobs();

Considering exceptions, I think that throwing an InvalidOperationException instead of something like SqlException is correct. Hangfire core isolated from details of a specific database.

Zoi answered 7/6, 2017 at 13:57 Comment(7)
But what if Hangfire developers will release newer version in which there will be another exception? Or no exception will be thrown? It still looks more like a hack. That is why i am asking about some other solution. Anyway thank you for your response!Shrive
@Shrive exception type change is definitely a breaking change so it shouldn't happen accidentaly. Anyway, what is the problem to catch all exceptions and check JobStorage.Current for a null? Actually JobStorage.Current just does a null-check itself, look at its source code: github.com/HangfireIO/Hangfire/blob/master/src/Hangfire.Core/…Zoi
@Shrive even more, you could execute a database query to test the connection. I added the example to the answer.Zoi
What is the point in connection testing if both JobStorage.Current == null and JobStorage.Current.GetConnection().GetRecurringJobs() will throw the same exception?Shrive
@Shrive it is your idea to predict possible future API changes, for example "if no exception will be thrown". For now it's enough to check JobStorage.Current only, you're right.Zoi
Ok, let it be the answer. IMHO, little addition ofHangfire.GlobalConfiguration.JobStorage.IsInitialized from the developers is preferable way to go. I'm not even talking about some connection fail policy. Thank you again for your answersShrive
You can also use GlobalConfiguration.Configuration.UseMemoryStorage(); if you want to run it in memory.Fascination
B
-1

Hi you can use this road:

1-Installing Hangfire->Hangfire.AspNetCore(v1.7.14) and Hangfire.Core(v1.7.14)

2-Registering Services

class Program
{
    static void Main(string[] args)
    {
        BuildWebHost(args).Run();
    }

    public static IWebHost BuildWebHost(string[] args)
    {
      return WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .Build();
    }
 }

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // Add Hangfire services.
        services.AddHangfire(configuration => configuration
            .SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
            .UseSimpleAssemblyNameTypeSerializer()
            .UseRecommendedSerializerSettings()
            .UseSqlServerStorage("Server=-; Database=-; user=-; password=-;"));

        // Add the processing server as IHostedService
        services.AddHangfireServer();
     }

3- Adding Dashboard UI

public void Configure(IApplicationBuilder app, IBackgroundJobClient 
                      backgroundJobs, IHostingEnvironment env)
    {
        app.UseHangfireDashboard();
        backgroundJobs.Enqueue(() => Console.WriteLine("Hello world from 
                                                        Hangfire!"));
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
  }

4- Running Application The following message should also appear, since we created background job, whose only behavior is to write a message to the console. Hello world from Hangfire!

Belfast answered 4/10, 2020 at 7:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.