Search code examples
c#asp.net-corehangfire

How can I get a Hangfire job's end time?


Given a Hangfire job's ID, how can I get the time at which the job finished running?

I've tried the below, but the JobData class doesn't have a property for job end time.

IStorageConnection connection = JobStorage.Current.GetConnection();
JobData jobData = connection.GetJobData(jobId);

Solution

  • I have had a similar requirement before. Here is a method I wrote to get the SucceededAt property using the name of the running method and the current PerformContext:

    public static DateTime? GetCompareDate(PerformContext context, string methodName)
    {
        return long.TryParse(context.BackgroundJob.Id, out var currentJobId)
            ? JobStorage.Current
                ?.GetMonitoringApi()
                ?.SucceededJobs(0, (int)currentJobId)
                ?.LastOrDefault(x => x.Value?.Job?.Method?.Name == methodName).Value?.SucceededAt
            : null;
    }
    

    You could just as easily get DeletedJobs, EnqueuedJobs, FailedJobs, etc.

    You can call it from a job method like this:

    public async Task SomeJob(PerformContext context, CancellationToken token)
    {
        ⋮
        var compareDate = GetCompareDate(context, nameof(SomeJob));
        ⋮
    }
    

    You just have to add the PerformContext when adding the job by passing in null:

    RecurringJobManager.AddOrUpdate(
            recurringJobId: "1",
            job: Job.FromExpression(() => SomeJob(null, CancellationToken.None)),
            cronExpression: Cron.Hourly(15),
            options: new RecurringJobOptions
            {
                TimeZone = TimeZoneInfo.Local
            });
    

    Note: It will only work if the succeeded job has not expired yet. Successful jobs expire after one day - if you need to keep them longer (to get the SucceededAt property), here is a reference for that: How to configure the retention time of job?