Open LymeHS opened 4 years ago
We experience the same effect. With ASPNETCORE_ENVIRONMENT=Development
everything works fine, but when we switch to ASPNETCORE_ENVIRONMENT=Production
, we get the same error. We haven't found a solution yet.
Other posts on the internet suggest adding
JobStorage.Current = new PostgreSqlStorage(configuration.GetConnectionString("DefaultConnection"));
but this doesn't help either.
Getting the same error as above but in my case, I'm trying to schedule a job but the server hasn't got the connection to PostgreSQL yet. A workaround was to add the jobs using the thread pool,
// An extension method called during Startup.cs
{
ThreadPool.QueueUserWorkItem(DelayedJobs);
return serviceCollection;
}
private static void DelayedJobs(object stateInfo)
{
// Delay startup for 5 minutes to be sure
// everything is up and running
Thread.Sleep(TimeSpan.FromMinutes(5));
// Schedule jobs
BackgroundJob.EnqueueT>(
methodCall: doStuff => updateCampaignAnalytics.Run());
}
Is there a way to save the job in memory before a connection is established?
Hi!
I have a similar behavior.
Since I upgraded my project from .NET Core 3.1 to .NET 6.0 with the minimal hosting model, I get the same error:
JobStorage.Current property value has not been initialized. You must set it before using Hangfire Client or Server API.
Even though the code (regarding Hangfire) hasn't changed (except of course it's now within the minimal hosting model). The code looks something like this:
...
// Add Hangfire services
builder.Services.AddHangfire(configuration => configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UsePostgreSqlStorage(builder.Configuration.GetConnectionString("HangfireConnection")));
...
builder.Services.AddHangfireServer();
...
var app = builder.Build();
...
if (builder.Environment.IsDevelopment())
{
app.UseHangfireDashboard();
}
// remove all Recurring-Jobs
using (var connection = JobStorage.Current.GetConnection())
{
foreach (var recurringJob in StorageConnectionExtensions.GetRecurringJobs(connection))
{
RecurringJob.RemoveIfExists(recurringJob.Id);
}
}
// add those Recurring-Jobs we need
RecurringJob.AddOrUpdate<CronJobs>(cj => cj.MyMethod1(), Cron.Weekly);
RecurringJob.AddOrUpdate<CronJobs>(cj => cj.MyMethod2(), Cron.Hourly);
// log all added Recurring-Jobs
using (var connection = JobStorage.Current.GetConnection())
{
foreach (var recurringJob in StorageConnectionExtensions.GetRecurringJobs(connection))
{
log.Info("add job=" + recurringJob.Id + " cron=" + recurringJob.Cron);
}
}
...
app.Run();
This error only occurs in production environment. In my development environment I have no problems and everything works fine.
This is probably since I'm using app.UseHangfireDashboard();
in development environment only. As soon as I comment app.UseHangfireDashboard();
out, the exception also occurs in my development environment.
I found a workaround. Adding the line app.Services.GetService<IBackgroundJobClient>();
seems to fix this:
...
// Add Hangfire services
builder.Services.AddHangfire(configuration => configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UsePostgreSqlStorage(builder.Configuration.GetConnectionString("HangfireConnection")));
...
builder.Services.AddHangfireServer();
...
var app = builder.Build();
...
if (builder.Environment.IsDevelopment())
{
app.UseHangfireDashboard();
}
else
{
app.Services.GetService<IBackgroundJobClient>(); // I added this line!
}
// remove all Recurring-Jobs
using (var connection = JobStorage.Current.GetConnection())
{
foreach (var recurringJob in StorageConnectionExtensions.GetRecurringJobs(connection))
{
RecurringJob.RemoveIfExists(recurringJob.Id);
}
}
// add those Recurring-Jobs we need
RecurringJob.AddOrUpdate<CronJobs>(cj => cj.MyMethod1(), Cron.Weekly);
RecurringJob.AddOrUpdate<CronJobs>(cj => cj.MyMethod2(), Cron.Hourly);
// log all added Recurring-Jobs
using (var connection = JobStorage.Current.GetConnection())
{
foreach (var recurringJob in StorageConnectionExtensions.GetRecurringJobs(connection))
{
log.Info("add job=" + recurringJob.Id + " cron=" + recurringJob.Cron);
}
}
...
app.Run();
But I believe this should be something Hangfire should handle internally...
Maybe Hangfire isn't ready for the new minimal hosting model?
Please try using IRecurringJobManager
service instead of static RecurringJob
class and JobStorage
service instead of static JobStorage.Current
property (and the same with IBackgroundJobClient
instead of BackgroundJob
):
var backgroundJobs = app.Services.GetService<IBackgroundJobClient>();
var recurringJobs = app.Services.GetService<IRecurringJobManager>();
var storage = app.Services.GetService<JobStorage>();
using (var connection = storage.GetConnection())
{
foreach (var recurringJob in StorageConnectionExtensions.GetRecurringJobs(connection))
{
recurringJobs.RemoveIfExists(recurringJob.Id);
}
}
// add those Recurring-Jobs we need
recurringJobs.AddOrUpdate<CronJobs>(cj => cj.MyMethod1(), Cron.Weekly);
recurringJobs.AddOrUpdate<CronJobs>(cj => cj.MyMethod2(), Cron.Hourly);
Hi!
I have a similar behavior.
Since I upgraded my project from .NET Core 3.1 to .NET 6.0 with the minimal hosting model, I get the same error:
JobStorage.Current property value has not been initialized. You must set it before using Hangfire Client or Server API.
Even though the code (regarding Hangfire) hasn't changed (except of course it's now within the minimal hosting model). The code looks something like this:
... // Add Hangfire services builder.Services.AddHangfire(configuration => configuration .SetDataCompatibilityLevel(CompatibilityLevel.Version_170) .UseSimpleAssemblyNameTypeSerializer() .UseRecommendedSerializerSettings() .UsePostgreSqlStorage(builder.Configuration.GetConnectionString("HangfireConnection"))); ... builder.Services.AddHangfireServer(); ... var app = builder.Build(); ... if (builder.Environment.IsDevelopment()) { app.UseHangfireDashboard(); } // remove all Recurring-Jobs using (var connection = JobStorage.Current.GetConnection()) { foreach (var recurringJob in StorageConnectionExtensions.GetRecurringJobs(connection)) { RecurringJob.RemoveIfExists(recurringJob.Id); } } // add those Recurring-Jobs we need RecurringJob.AddOrUpdate<CronJobs>(cj => cj.MyMethod1(), Cron.Weekly); RecurringJob.AddOrUpdate<CronJobs>(cj => cj.MyMethod2(), Cron.Hourly); // log all added Recurring-Jobs using (var connection = JobStorage.Current.GetConnection()) { foreach (var recurringJob in StorageConnectionExtensions.GetRecurringJobs(connection)) { log.Info("add job=" + recurringJob.Id + " cron=" + recurringJob.Cron); } } ... app.Run();
This error only occurs in production environment. In my development environment I have no problems and everything works fine. This is probably since I'm using
app.UseHangfireDashboard();
in development environment only. As soon as I commentapp.UseHangfireDashboard();
out, the exception also occurs in my development environment.
I am experiencing the same issue. If I use 'app.UseHangfireDashboard()' before calling 'BackgroundJob.Enqueue()', there are no errors. If I execute 'BackgroundJob.Enqueue()' before 'app.UseHangfireDashboard()', the exception is thrown. To fix this, I used the workaround mentioned on other responses: call 'app.Services.GetService
Hello, we're new to hangfire and trying to get it running. We're using an old ASP.net build with a global.asax file instead of a startup file. We have two different enviorments, dev and staging.
The code is identical, except for the connection string for the database, as it is located on a different server. Everything works great in Dev. The tables get created, the jobs run. But when we migrated over to staging, we're getting the following error, and the Hangfire tables fail to create:
JobStorage.Current property value has not been initialized. You must set it before using Hangfire Client or Server API
Like I said, everything works fine in our dev enviorment, but in staging we get that error and the tables also fail to create. I'm assuming it's an issue connection to the database or something with permissions? Can anyone that understands this error elaborate on that at all?