Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hangfire runs missed Jobs after server wakes up, can it be prevented? #620

Open
evaldas-raisutis opened this issue Jul 20, 2016 · 8 comments

Comments

@evaldas-raisutis
Copy link

commented Jul 20, 2016

By default, it seems, hangfire will attempt to run jobs it has missed, if for example, server was down when jobs were supposed to be run. I would like to disable this functionality. We have jobs which import products into a webshop, and for the duration of an import site becomes quite unresponsive due to resources used by the import.

Problem is we only want to run jobs at night OR when triggered manually through UI. Can I disable hangfire trying to run missed jobs after startup?

@Darrenmeehan

This comment has been minimized.

Copy link

commented Jul 26, 2016

This is also something I've to look into further, also with an import job.

@DBalashov

This comment has been minimized.

Copy link

commented Aug 4, 2016

I also can't found solution, but insert additional checking in start of job for time. For example, if job scheduled at 3:00 AM - I'm check current time inside job for 3:00 AM +/- 10 minutes. Job aborted if difference more than 10 minutes.

@evaldas-raisutis

This comment has been minimized.

Copy link
Author

commented Aug 31, 2016

@DBalashov that works on scheduled executions, but I also want to be able to execute the job manually when necessary.

@evaldas-raisutis

This comment has been minimized.

Copy link
Author

commented Aug 31, 2016

It seems on coming back from idle, hangfire will grab jobs which were to be executed in the past and sets NextExecution to Now. It would be nice if there was a setting to prevent this.

@enrichz

This comment has been minimized.

Copy link

commented Jun 20, 2018

Any update on this?

@CBlaize

This comment has been minimized.

Copy link

commented Feb 21, 2019

This feature is also a requirement for my use case. Jobs are expected to ONLY run at the designated time. If the server was down at the designated time or it failed then it cannot be re-run at any later date. period.

I thought this would have sufficed, but it does not appear to stop jobs from automatically starting on startup.

GlobalJobFilters.Filters.Add(new AutomaticRetryAttribute { Attempts = 0 });

@pieceofsummer

This comment has been minimized.

Copy link
Contributor

commented Feb 22, 2019

The recurring job scheduler only checks if there should be a scheduled execution since the previous job run, and triggers the job if needed. It doesn't care if the scheduled time is missed for 1 second or a few days.

I'd try to go with a client filter that would cancel "late" jobs:

public class NoMissedRunsAttribute : JobFilterAttribute, IClientFilter
{
    public TimeSpan MaxDelay { get; set; } = TimeSpan.FromMinutes(15);
    
    public void OnCreating(CreatingContext context)
    {
        if (context.Parameters.TryGetValue("RecurringJobId", out var recurringJobId) &&
            context.InitialState?.Reason == "Triggered by recurring job scheduler")
        {
            // the job being created looks like a recurring job instance,
            // and triggered by a scheduler (i.e. not manually) at that.
            
            var recurringJob = context.Connection.GetAllEntriesFromHash($"recurring-job:{recurringJobId}");
            
            if (recurringJob != null && recurringJob.TryGetValue("NextExecution", out var nextExecution))
            {
                // 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);
                
                if (DateTime.UtcNow > scheduledTime + MaxDelay)
                {
                    // the job is created way later than expected
                    context.Canceled = true;
                }
            }
        }
    }

    public void OnCreated(CreatedContext context)
    {
    }
}

I haven't tested it though, so it may require some adjustments before it actually works :)

@5p1k3md

This comment has been minimized.

Copy link

commented Aug 25, 2019

Hello,

i just ried the solution from @pieceofsummer .
Unfortunately there is no initial state given with the compared string given at any time.
Is there an other way to determ a rerunning recurring job after server restart?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
8 participants
You can’t perform that action at this time.