Ejemplo n.º 1
0
        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)));
        }
Ejemplo n.º 2
0
        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 factory = scopedContext.Provider.GetService <IJobFactory>();
                    var job     = (IJob)factory.Create(computedJob.JobType);
                    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)
                    {
                        now = DateTime.UtcNow;
                        computedJob.Update(now);
                        using (var scope = _provider.CreateScope())
                        {
                            var provider   = scope.ServiceProvider;
                            var connection = provider.GetRequiredService <IStorageConnection>();

                            await connection.UpdateCronJobAsync(computedJob.Job);
                        }
                    }
                }
            }
        }
        public void UpdateNext_LastRun_AfterPrev_SchedulesNormal()
        {
            // Arrange
            var now      = new DateTime(2000, 1, 1, 8, 0, 0);
            var cronJob  = new CronJob(Cron.Daily(), now.Subtract(TimeSpan.FromSeconds(5)));
            var computed = new ComputedCronJob(cronJob);

            // Act
            computed.UpdateNext(now);

            // Assert
            computed.Next.Should().BeAfter(now);
        }
        public void UpdateNext_LastRun_BeforePrev_SchedulesNow()
        {
            // Arrange
            var now      = new DateTime(2000, 1, 1, 8, 0, 0);
            var cronJob  = new CronJob(Cron.Daily(), now.Subtract(TimeSpan.FromDays(2)));
            var computed = new ComputedCronJob(cronJob);

            // Act
            computed.UpdateNext(now);

            // Assert
            computed.Next.Should().Be(now);
        }
        public void UpdateNext_LastRunNever_SchedulesNow()
        {
            // Arrange
            var now      = new DateTime(2000, 1, 1, 8, 0, 0);
            var cronJob  = new CronJob(Cron.Daily());
            var computed = new ComputedCronJob(cronJob);

            // Act
            computed.UpdateNext(now);

            // Assert
            computed.Next.Should().Be(now);
        }