gpt4 book ai didi

asp.net-mvc - 如果 Hangfire 已在运行,则停止启动重复作业

转载 作者:行者123 更新时间:2023-12-02 01:44:08 24 4
gpt4 key购买 nike

我在 Hangfire 中设置了一个定期作业列表,所有作业的间隔均为 20 分钟。

它们都调用相同的方法,但参数不同。例如

作业 ID test_1 => MyTestMethod(1)
作业 ID test_50 => MyTestMethod(50)
作业 ID test_37 => MyTestMethod(37)

有时,作业可能需要比其间隔更长的时间,即超过 20 分钟,并且我想确保该作业在另一个实例已经运行时不会再次运行。

DisableConcurrentExecutionAttribute在这里不适合,因为该方法可以同时运行,只是参数不同。

我试图拥有静态 Dictionary<string, DateTime>它跟踪作业是否已经在运行,以便它可以阻止并发方法调用,但问题是,如果应用程序因任何原因重新启动,那么它会“忘记”当前正在运行哪些作业(Hangfire 当然会继续运行在背景)。

更新
我还尝试在数据库中添加一个 JobState 表来跟踪哪些作业正在运行,然后在 MyTestMethod 启动时检查该表,但这依赖于 MyTestMethod 设置 running=1 。启动时running=0当它结束时,如果线程在该作业中途崩溃(无论出于何种原因),则可能不会发生,从而根本阻止作业再次运行。

我确信我可以通过简单地通过作业 ID 查询 Hangfire 作业状态来解决这个问题 - 我只是找不到如何执行此操作?

最佳答案

我有类似的要求,基本上我想使用DisableConcurrentExecutionAttribute,但让它考虑参数。这样,如果一个作业使用相同的参数排队,它仍然会运行,只是不并行。我以DisableMultipleQueuedItemsFilter 为例,它实际上删除了作业并修改了DisableConcurrentExecutionAttribute 以使用参数。不同之处在于,如果作业具有相同的参数列表,则作业将排队,它们不会并行运行。

可以在此处查看包含两个属性的完整示例:https://gist.github.com/sbosell/3831f5bb893b20e82c72467baf8aefea

该属性的相关代码:

 public class DisableConcurrentExecutionWithParametersAttribute : JobFilterAttribute, IServerFilter
{
private readonly int _timeoutInSeconds;

public DisableConcurrentExecutionWithParametersAttribute (int timeoutInSeconds)
{
if (timeoutInSeconds < 0) throw new ArgumentException("Timeout argument value should be greater that zero.");

_timeoutInSeconds = timeoutInSeconds;
}

public void OnPerforming(PerformingContext filterContext)
{
var resource = GetResource(filterContext.BackgroundJob.Job);

var timeout = TimeSpan.FromSeconds(_timeoutInSeconds);

var distributedLock = filterContext.Connection.AcquireDistributedLock(resource, timeout);
filterContext.Items["DistributedLock"] = distributedLock;
}

public void OnPerformed(PerformedContext filterContext)
{
if (!filterContext.Items.ContainsKey("DistributedLock"))
{
throw new InvalidOperationException("Can not release a distributed lock: it was not acquired.");
}

var distributedLock = (IDisposable)filterContext.Items["DistributedLock"];
distributedLock.Dispose();
}

private static string GetFingerprint(Job job)
{
var parameters = string.Empty;
if (job?.Arguments != null)
{
parameters = string.Join(".", job.Arguments);
}
if (job?.Type == null || job.Method == null)
{
return string.Empty;
}
var payload = $"{job.Type.FullName}.{job.Method.Name}.{parameters}";
var hash = SHA256.Create().ComputeHash(System.Text.Encoding.UTF8.GetBytes(payload));
var fingerprint = Convert.ToBase64String(hash);
return fingerprint;
}
private static string GetResource(Job job)
{
return GetFingerprint(job);
}
}

关于asp.net-mvc - 如果 Hangfire 已在运行,则停止启动重复作业,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37589279/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com