public async Task ProcessAsync(ProcessingContext context)
        {
            _logger.CollectingExpiredEntities();

            foreach (var table in Tables)
            {
                var removedCount = 0;
                do
                {
                    using (var scope = _provider.CreateScope())
                    {
                        var provider      = scope.ServiceProvider;
                        var jobsDbContext = provider.GetService <TContext>();
                        var connection    = jobsDbContext.GetDbConnection();

                        removedCount = await connection.ExecuteAsync(
                            CreateDeleteTopQuery(_options.Schema, table),
                            new { now = DateTime.UtcNow, count = MaxBatch });
                    }

                    if (removedCount != 0)
                    {
                        await context.WaitAsync(_delay);

                        context.ThrowIfStopping();
                    }
                } while (removedCount != 0);
            }

            await context.WaitAsync(_waitingInterval);
        }
        public async Task ProcessAsync(ProcessingContext context)
        {
            _logger.CollectingExpiredEntities();

            var storage = context.Storage as SqlServerStorage;

            foreach (var table in Tables)
            {
                var removedCount = 0;
                do
                {
                    using (var scope = _provider.CreateScope())
                    {
                        var provider      = scope.ServiceProvider;
                        var jobsDbContext = provider.GetService <JobsDbContext>();
                        var connection    = jobsDbContext.GetDbConnection();

                        removedCount = await connection.ExecuteAsync($@"
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
DELETE TOP (@count) FROM [{_options.Schema}].[{table}] WITH (readpast) WHERE ExpiresAt < @now;",
                                                                     new { now = DateTime.UtcNow, count = MaxBatch });
                    }

                    if (removedCount != 0)
                    {
                        await context.WaitAsync(_delay);

                        context.ThrowIfStopping();
                    }
                } while (removedCount != 0);
            }

            await context.WaitAsync(_waitingInterval);
        }
Ejemplo n.º 3
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);
                        }
                    }
                }
            }
        }