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); } } } } }
private async Task <bool> Step(ProcessingContext context) { var fetched = default(IFetchedJob); using (var scope = _provider.CreateScope()) { var provider = scope.ServiceProvider; var connection = provider.GetRequiredService <IStorageConnection>(); if ((fetched = await connection.FetchNextJobAsync()) != null) { using (fetched) using (var scopedContext = context.CreateScope()) { var job = await connection.GetJobAsync(fetched.JobId); var invocationData = Helper.FromJson <InvocationData>(job.Data); var method = invocationData.Deserialize(); var factory = scopedContext.Provider.GetService <IJobFactory>(); var instance = default(object); if (!method.Method.IsStatic) { instance = factory.Create(method.Type); } try { var sp = Stopwatch.StartNew(); await _stateChanger.ChangeStateAsync(job, new ProcessingState(), connection); if (job.Retries > 0) { _logger.JobRetrying(job.Retries); } var result = await ExecuteJob(method, instance); sp.Stop(); var newState = default(IState); if (!result.Succeeded) { var shouldRetry = await UpdateJobForRetryAsync(instance, job, connection); if (shouldRetry) { newState = new ScheduledState(); _logger.JobFailedWillRetry(result.Exception); } else { newState = new FailedState(); _logger.JobFailed(result.Exception); } } else { newState = new SucceededState(); } await _stateChanger.ChangeStateAsync(job, newState, connection); fetched.RemoveFromQueue(); if (result.Succeeded) { _logger.JobExecuted(sp.Elapsed.TotalSeconds); } } catch (JobLoadException ex) { _logger.JobCouldNotBeLoaded(job.Id, ex); await _stateChanger.ChangeStateAsync(job, new FailedState(), connection); fetched.RemoveFromQueue(); } catch (Exception ex) { _logger.ExceptionOccuredWhileExecutingJob(job.Id, ex); fetched.Requeue(); } } } } return(fetched != null); }