Hangfire.HttpJob icon indicating copy to clipboard operation
Hangfire.HttpJob copied to clipboard

使用HangfireJobAgent,和服务端在同一个netcore的微服务

Open githubcopilottime opened this issue 1 year ago • 2 comments

发现在服务重启后,周期性任务全部会执行一次,后续执行和日志都是正常的,能否在服务重启时,不让任务执行的?

githubcopilottime avatar Dec 11 '24 06:12 githubcopilottime

I solved it using this filter: NoMissedRunsAttribute

Image

I shared my code:

` public class NoMissedRunsAttribute : JobFilterAttribute, IClientFilter { private static readonly ILog Logger = LogProvider.GetCurrentClassLogger(); public int MaxDelayMs { get; set; } = (int)TimeSpan.FromMinutes(1).TotalMilliseconds;

public void OnCreating(CreatingContext filterContext)
{
    Logger.InfoFormat("Creating a job based on method {0}...", filterContext.Job.Method.Name);
    if (filterContext.Parameters.TryGetValue("RecurringJobId", out var recurringJobId))
    {
        // the job being created looks like a recurring job instance.

        var recurringJob = filterContext.Connection.GetAllEntriesFromHash($"recurring-job:{recurringJobId}");

        if (recurringJob != null && recurringJob.TryGetValue("NextExecution", out var nextExecution))
        {
            var utcNow = DateTime.UtcNow;

            // the next execution time of a recurring job is updated AFTER the job instance creation,
            // so at the moment it still contains the scheduled execution time from the previous run.
            var scheduledTime = JobHelper.DeserializeDateTime(nextExecution);

            // Check if the job is created way later than expected
            // and if it was created from the scheduler.
            if (utcNow > scheduledTime.AddMilliseconds(MaxDelayMs) && IsCreatedFromRecurringJobScheduler())
            {
                Logger.WarnFormat(
                    "Job '{0}' has been cancelled to avoid missed execution on startup",
                    filterContext.Job.Method.Name);
                filterContext.Canceled = true;
            }
        }
    }
}

private static bool IsCreatedFromRecurringJobScheduler()
{
    // Get call stack
    var stackTrace = new StackTrace();
    return stackTrace.GetFrames().Any(f => f.GetMethod()?.DeclaringType == typeof(RecurringJobScheduler));
}

public void OnCreated(CreatedContext filterContext)
{
    // Nothing to do.
}

} `

Enjoy!

maxiar avatar Feb 13 '25 17:02 maxiar

nice @maxiar

yuzd avatar Feb 14 '25 00:02 yuzd