private DateTime ComputeDue(ComputedCronJob computedJob, DateTime now) { computedJob.UpdateNext(now); var retryBehavior = computedJob.RetryBehavior ?? RetryBehavior.DefaultRetry; var retries = computedJob.Retries; if (retries == 0) { return(computedJob.Next); } var realNext = computedJob.Schedule.GetNextOccurrence(now); if (!retryBehavior.Retry) { // No retry. If job failed before, we don't care, just schedule it next as usual. return(realNext); } if (retries >= retryBehavior.RetryCount) { // Max retries. Just schedule it for the next occurance. return(realNext); } // Delay a bit. return(computedJob.FirstTry.AddSeconds(retryBehavior.RetryIn(retries))); }
private async Task RunAsync(ComputedCronJob computedJob, ProcessingContext context) { //var storage = context.Storage; var retryBehavior = computedJob.RetryBehavior; while (!context.IsStopping) { var now = DateTime.UtcNow; var due = ComputeDue(computedJob, now); var timeSpan = due - now; if (timeSpan.TotalSeconds > 0) { await context.WaitAsync(timeSpan); } context.ThrowIfStopping(); using (var scopedContext = context.CreateScope()) { var provider = scopedContext.Provider; var job = provider.GetService <IJob>(); var success = true; try { var sw = Stopwatch.StartNew(); await job.ExecuteAsync(); sw.Stop(); computedJob.Retries = 0; _logger.CronJobExecuted(computedJob.Job.Name, sw.Elapsed.TotalSeconds); } catch (Exception ex) { success = false; if (computedJob.Retries == 0) { computedJob.FirstTry = DateTime.UtcNow; } computedJob.Retries++; _logger.CronJobFailed(computedJob.Job.Name, ex); } if (success) { computedJob.Update(DateTime.UtcNow); } } } }