Hangfire在服务器重新启动时复制作业

时间:2018-08-01 10:30:51

标签: c# .net-core scheduled-tasks hangfire

所以我们有一个.NET Core API,它使用hangfire作为任务调度程序。

启动时,我们的API将启动以下功能:

public void CreateTasks()
{
    /* DATABASE TASKS */
    SyncDatabaseTask();

    /* SMS TASKS */
    SendSmsTask();

}

public void SendSmsTask()
{
    var taskId = BackgroundJob.Schedule(() => _smsService.SendSms(), TimeSpan.FromMinutes(30));
    BackgroundJob.ContinueWith(taskId, () => SendSmsTask());
}

这会在启动时在Hangfire中创建作业SendSmsTask,并且在第一个作业完成之前不会启动第二个作业。

但是,我们刚刚注意到的问题是,每当我们的API重新启动(例如服务器更新)时,现有作业仍在运行,并且新闻作业正在添加。

因此,我们希望在启动时删除所有计划的或正在运行的作业。

我已经浏览了文档(http://docs.hangfire.io/en/latest/),但找不到真正的解决方案。

3 个答案:

答案 0 :(得分:1)

这应该可以解决您的问题,只是请注意,这未经测试。

    private void RemoveAllHangfireJobs()
    {
        var hangfireMonitor = JobStorage.Current.GetMonitoringApi();

        //RecurringJobs
        JobStorage.Current.GetConnection().GetRecurringJobs().ForEach(xx => BackgroundJob.Delete(xx.Id));

        //ProcessingJobs
        hangfireMonitor.ProcessingJobs(0, int.MaxValue).ForEach(xx => BackgroundJob.Delete(xx.Key));

        //ScheduledJobs
        hangfireMonitor.ScheduledJobs(0, int.MaxValue).ForEach(xx => BackgroundJob.Delete(xx.Key));

        //EnqueuedJobs
        hangfireMonitor.Queues().ToList().ForEach(xx => hangfireMonitor.EnqueuedJobs(xx.Name,0, int.MaxValue).ForEach(x => BackgroundJob.Delete(x.Key)));
    }

答案 1 :(得分:1)

如果您仍然对Pieter Alberts解决方案感兴趣。

对此稍有改动。

如果您使用旧代码并且在db中有旧工作,则将获得Format Exception。

// RecurringJobs 部分中,您必须像这样更改行:

JobStorage.Current.GetConnection().GetRecurringJobs().ForEach(xx => RecurringJob.RemoveIfExists(xx.Id));

TL; DR

旧代码:

private void RemoveAllHangfireJobs()
    {
        var hangfireMonitor = JobStorage.Current.GetMonitoringApi();

        //RecurringJobs
        JobStorage.Current.GetConnection().GetRecurringJobs().ForEach(xx => BackgroundJob.Delete(xx.Id));

        //ProcessingJobs
        hangfireMonitor.ProcessingJobs(0, int.MaxValue).ForEach(xx => BackgroundJob.Delete(xx.Key));

        //ScheduledJobs
        hangfireMonitor.ScheduledJobs(0, int.MaxValue).ForEach(xx => BackgroundJob.Delete(xx.Key));

        //EnqueuedJobs
        hangfireMonitor.Queues().ToList().ForEach(xx => hangfireMonitor.EnqueuedJobs(xx.Name,0, int.MaxValue).ForEach(x => BackgroundJob.Delete(x.Key)));
    }

新代码:

private void RemoveAllHangfireJobs()
    {
        var hangfireMonitor = JobStorage.Current.GetMonitoringApi();

        //RecurringJobs
        JobStorage.Current.GetConnection().GetRecurringJobs().ForEach(xx => RecurringJob.RemoveIfExists(xx.Id)); // this line changed!

        //ProcessingJobs
        hangfireMonitor.ProcessingJobs(0, int.MaxValue).ForEach(xx => BackgroundJob.Delete(xx.Key));

        //ScheduledJobs
        hangfireMonitor.ScheduledJobs(0, int.MaxValue).ForEach(xx => BackgroundJob.Delete(xx.Key));

        //EnqueuedJobs
        hangfireMonitor.Queues().ToList().ForEach(xx => hangfireMonitor.EnqueuedJobs(xx.Name,0, int.MaxValue).ForEach(x => BackgroundJob.Delete(x.Key)));
    }

PS编辑: 我的Hangfire版本是1.7.9 并使用Hangfire.PostgreSql

答案 2 :(得分:0)

            //Start Hangfire Server
        var varJobOptions = new BackgroundJobServerOptions();
        varJobOptions.ServerName = "job.fiscal.io";
        varJobOptions.WorkerCount = Environment.ProcessorCount * 10;
        app.UseHangfireServer(varJobOptions);
        app.UseHangfireDashboard("/jobs", new DashboardOptions {
            Authorization = new[] { new clsHangFireAuthFilter() }
        });
        //Remove Duplicte HangFire Server
        var varMonitoringApi = JobStorage.Current.GetMonitoringApi();
        var varServerList = varMonitoringApi.Servers().Where(r => r.Name.Contains("job.fiscal.io"));
        foreach( var varServerItem in varServerList) {
            JobStorage.Current.GetConnection().RemoveServer(varServerItem.Name);
        }