Search code examples
azureasp.net-core.net-coreasp.net-core-2.0hangfire

Alert getting scheduled an hour late when hosted on Azure


I'm using hangfire to schedule sending an email alert at a time specified by the user. when I test the app on localhost the alert is scheduled for the correct time, when i send a request to the live app hosted on Azure the request is scheduled for an hour later than it should be.

I assume the problem is my lack of knowledge on DateTimeOffset. What I am doing in my JobScheduler class is

    public class JobScheduler : IJobScheduler
    {
        private EmailManager _emailManager;

        public JobScheduler(IAlertManager alertManager)
        {
            _alertManager = alertManager;
        }
        public string ScheduleRaiseDateAlert( DateDetail date)
        {
            DateTimeOffset jobRunTime = ConvertToDateTimeOffSet(date.CheckInTime);
            return BackgroundJob.Schedule(()=> _alertManager.RaiseAlertAsync(date.Id, true), jobRunTime.DateTime);
        }
        private DateTimeOffset ConvertToDateTimeOffSet(DateTime futureDateTime)
        {
            futureDateTime = DateTime.SpecifyKind(futureDateTime, DateTimeKind.Utc);
            DateTimeOffset ScheduleTime = futureDateTime;
            return ScheduleTime;
        }
    }

date.CheckInTime is the datetime the user should be sent an email

for example: if date.CheckInTime = 17/04/2018 19:02:00 when i send the request on local host the job will be scheduled for that date and time, when i send the same request to the app hosted on azure the time the job is scheduled for is 17/04/2018 20:02:00


Solution

  • AFAIK, the DateTimeOffset.DateTime would be treated as a local date time, you could check the Kind property of your jobRunTime.DateTime instance sent to BackgroundJob.Schedule.

    For the method overloading for BackgroundJob.Schedule which supports the DateTimeOffset parameter, the stored EnqueueAt would be DateTimeOffset.UtcDateTime of your DateTimeOffset parameter.

    For the TimeSpan parameter, the stored EnqueueAt would be the current UTC date time adding your specified TimeSpan.

    Moreover, if you pass the local time DateTime instance to BackgroundJob.Schedule, the stored EnqueueAt would be converted to the relevant UTC date time.

    Since you did not provide how did you construct the DateDetail, I would recommend you to check the stored tasks to narrow down this issue. I used UseSqlServerStorage, for this approach, you could check the state of scheduled task under HangFire.State table.

    {"EnqueueAt":"2018-04-20T06:39:28.0305044Z","ScheduledAt":"2018-04-18T06:39:29.5398973Z"}
    

    The ScheduledAt stands for the UTC date time you created this task, the EnqueueAt stands for the UTC date time when the task would be triggered.