Пример #1
0
        /// <summary>
        /// Exponentially backoff the next run time of a job after every failure (Non-Terminal) upto a defined MAX.
        /// Currently, only one time jobs are exponentially backed off, and recurring jobs are just scheduled for next occurence.
        /// </summary>
        /// <param name="scheduler">
        /// Instance of the Scheduler
        /// </param>
        /// <param name="jobDetails">
        /// Scheduled Job Details.
        /// </param>
        /// <returns>
        /// Async Task Wrapper
        /// </returns>
        public static async Task ExponentiallyBackoffAsync(this IScheduler scheduler, ScheduledJobDetails jobDetails, CommerceLog log)
        {
            // this branch should not happen once we schedule the job once.
            if (jobDetails != null && jobDetails.Recurrence != null)
            {
                // if job is scheduled to run only once
                if (jobDetails.Recurrence.Count == 1)
                {
                    // initialize retry count if it does not exist
                    if (jobDetails.Payload == null)
                    {
                        jobDetails.Payload = new Dictionary <string, string>();
                        jobDetails.Payload["RetryCount"] = "0";
                    }
                    else if (!jobDetails.Payload.ContainsKey("RetryCount"))
                    {
                        jobDetails.Payload["RetryCount"] = "0";
                    }

                    int retryCount;
                    if (!int.TryParse(jobDetails.Payload["RetryCount"], out retryCount))
                    {
                        retryCount = 0;
                    }

                    //Important: Since the job is a run once job, so recurrence for the next retry is solely
                    // dependent on the retry interval. Past recurrence is immaterial.
                    jobDetails.Recurrence = new Recurrence()
                    {
                        Frequency = RecurrenceFrequency.Second,
                        Count     = 1,
                        Interval  = GetWaitTimeInSeconds(retryCount)
                    };

                    log.Verbose("Job Id {0} has been retried {1} times, back off to try the next time after {2} seconds",
                                jobDetails.JobId,
                                retryCount,
                                jobDetails.Recurrence.Interval);

                    // increment retry count in payload
                    jobDetails.Payload["RetryCount"] = (retryCount + 1).ToString(CultureInfo.InvariantCulture);

                    // schedule it to run later
                    await scheduler.UpdateJobAsync(jobDetails).ConfigureAwait(false);
                }
                else // recurring job
                {
                    // just mark current iteration as done. We will try again next time
                    await scheduler.CompleteJobIterationAsync(jobDetails).ConfigureAwait(false);
                }
            }
            else
            {
                log.Warning("After first run of job, job or recurrence should not be null.");
                await Task.Factory.StartNew(() => { }).ConfigureAwait(false);
            }
        }