public string Schedule([NotNull, InstantHandle] Expression <Func <Task> > action, TimeSpan enqueueIn, JobContinuationOptions atomProgress = JobContinuationOptions.OnlyOnSucceededState) { var state = new ScheduledState(enqueueIn); return(CreateSubatomInternal(action, state, atomProgress)); }
public string Schedule([NotNull, InstantHandle] Expression <Action> action, DateTime enqueueAt, JobContinuationOptions atomProgress = JobContinuationOptions.OnlyOnSucceededState) { var state = new ScheduledState(enqueueAt); return(CreateSubatomInternal(action, state, atomProgress)); }
public void Ctor_SetsTheCorrectDate_WhenTimeSpanIsPassed() { var state = new ScheduledState(TimeSpan.FromDays(1)); Assert.True(DateTime.UtcNow.AddDays(1).AddMinutes(-1) < state.EnqueueAt); Assert.True(state.EnqueueAt < DateTime.UtcNow.AddDays(1).AddMinutes(1)); }
public void ClearScheduled() { this.scheduledDuckState_ = ScheduledState.UNDEFINED; this.HeldXAxis = 0; this.IsRunning = false; this.scheduledJumpState_ = ScheduledState.UNDEFINED; }
public void Ctor_SetsTheCorrectData_WhenDateIsPassed() { var date = new DateTime(2012, 12, 12); var state = new ScheduledState(date); Assert.Equal(date, state.EnqueueAt); }
private IState GetNewState(OperateResult result, CapReceivedMessage message) { IState newState; if (!result.Succeeded) { var shouldRetry = UpdateMessageForRetry(message); if (shouldRetry) { newState = new ScheduledState(); _logger.JobFailedWillRetry(result.Exception); } else { newState = new FailedState(); _logger.JobFailed(result.Exception); } AddErrorReasonToContent(message, result.Exception); } else { newState = new SucceededState(_options.SucceedMessageExpiredAfter); } return(newState); }
public async Task <OperateResult> ExecuteAsync(IStorageConnection connection, IFetchedMessage fetched) { var message = await connection.GetReceivedMessageAsync(fetched.MessageId); try { var sp = Stopwatch.StartNew(); await _stateChanger.ChangeStateAsync(message, new ProcessingState(), connection); if (message.Retries > 0) { _logger.JobRetrying(message.Retries); } var result = await ExecuteSubscribeAsync(message); sp.Stop(); var newState = default(IState); if (!result.Succeeded) { var shouldRetry = await UpdateMessageForRetryAsync(message, 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(message, newState, connection); fetched.RemoveFromQueue(); if (result.Succeeded) { _logger.JobExecuted(sp.Elapsed.TotalSeconds); } return(OperateResult.Success); } catch (SubscriberNotFoundException ex) { _logger.LogError(ex.Message); return(OperateResult.Failed(ex)); } catch (Exception ex) { _logger.ExceptionOccuredWhileExecutingJob(message?.Name, ex); return(OperateResult.Failed(ex)); } }
public void Execute(BackgroundProcessContext context) { context.CancellationToken.ThrowIfCancellationRequested(); var queueJob = _storage.FetchNextJob(this._queues, this._workerId); if (queueJob == null) { context.Wait(_workerFetchIdleSleep); return; } _storage.SetJobState(queueJob.JobId, new ProcessingState(context.ServerId, this._workerId)); _eventManager.RaiseOnProcessing(queueJob, context.ServerId, this._workerId); var perfomContext = new PerformContext(context.CancellationToken, queueJob); var resultState = PerformJob(perfomContext); if (resultState is FailedState) { var failedState = resultState as FailedState; if (queueJob.RetryCount < queueJob.MaxRetries) { //schedule new run var nextRun = DateTime.UtcNow.AddSeconds(SecondsToDelay(queueJob.RetryCount)); const int maxMessageLength = 50; var exceptionMessage = failedState.Exception.Message.Length > maxMessageLength ? failedState.Exception.Message.Substring(0, maxMessageLength - 1) + "…" : failedState.Exception.Message; var scheduledState = new ScheduledState(nextRun) { Reason = $"Retry attempt { queueJob.RetryCount } of { queueJob.MaxRetries }: { exceptionMessage}" }; _storage.UpgradeFailedToScheduled(queueJob.JobId, resultState, scheduledState, nextRun, queueJob.RetryCount + 1); _eventManager.RaiseOnReschedule(queueJob, context.ServerId, this._workerId, failedState.Exception, nextRun); } else { //final failed state _storage.SetJobState(queueJob.JobId, resultState); _eventManager.RaiseOnFail(queueJob, context.ServerId, this._workerId, failedState.Exception); if (queueJob.WorkflowId.HasValue) { //mark dependent jobs consequently failed _storage.MarkConsequentlyFailedJobs(queueJob.JobId); } } } else { //Succeeded _storage.SetJobState(queueJob.JobId, resultState); _storage.ExpireJob(queueJob.JobId); _storage.EnqueueAwaitingWorkflowJobs(queueJob.JobId); _eventManager.RaiseOnSuccess(queueJob, context.ServerId, this._workerId); } _storage.RemoveFromQueue(queueJob.QueueJobId); }
public static void GetCreatedAt_ReturnsCorrectValue_ScheduledState() { var state = new ScheduledState(new TimeSpan(1, 0, 0)); var result = state.GetCreatedAt(); Assert.Equal(state.ScheduledAt, result); Assert.NotEqual(state.EnqueueAt, result); }
public void SerializeData_ReturnsCorrectData() { var state = new ScheduledState(new DateTime(2012, 12, 12)); var data = state.SerializeData(); Assert.Equal(JobHelper.ToStringTimestamp(state.EnqueueAt), data["EnqueueAt"]); Assert.Equal(JobHelper.ToStringTimestamp(state.ScheduledAt), data["ScheduledAt"]); }
public void CreateInScheduledState() { #region ScheduledState var client = new BackgroundJobClient(); var state = new ScheduledState(TimeSpan.FromHours(2)); client.Create(() => Console.WriteLine("Hello!"), state); #endregion }
public string ScheduleJob(enSuspendOption suspendOption, string suspendOptionValue, Dictionary <string, StringBuilder> values) { var suspensionDate = DateTime.Now; var resumptionDate = CalculateResumptionDate(suspensionDate, suspendOption, suspendOptionValue); var state = new ScheduledState(resumptionDate.ToUniversalTime()); var jobId = _client.Create(() => ResumeWorkflow(values, null), state); return(jobId); }
public async Task <OperateResult> ExecuteAsync(IStorageConnection connection, IFetchedMessage fetched) { var message = await connection.GetPublishedMessageAsync(fetched.MessageId); try { var sp = Stopwatch.StartNew(); await _stateChanger.ChangeStateAsync(message, new ProcessingState(), connection); if (message.Retries > 0) { _logger.JobRetrying(message.Retries); } var result = await PublishAsync(message.Name, message.Content); sp.Stop(); IState newState; if (!result.Succeeded) { var shouldRetry = UpdateMessageForRetryAsync(message); if (shouldRetry) { newState = new ScheduledState(); _logger.JobFailedWillRetry(result.Exception); } else { newState = new FailedState(); _logger.JobFailed(result.Exception); } message.Content = Helper.AddExceptionProperty(message.Content, result.Exception); } else { newState = new SucceededState(_options.SucceedMessageExpiredAfter); } await _stateChanger.ChangeStateAsync(message, newState, connection); fetched.RemoveFromQueue(); if (result.Succeeded) { _logger.JobExecuted(sp.Elapsed.TotalSeconds); } return(OperateResult.Success); } catch (Exception ex) { fetched.Requeue(); _logger.ExceptionOccuredWhileExecuting(message?.Name, ex); return(OperateResult.Failed(ex)); } }
public void JsonSerialize_ReturnsCorrectString_After170() { var dateTime = DateTime.UtcNow; var state = new ScheduledState(dateTime); var convertedDateTime = JsonConvert.SerializeObject(dateTime); var serialized = SerializationHelper.Serialize <IState>(state, SerializationOption.TypedInternal); Assert.Equal( "{\"$type\":\"Hangfire.States.ScheduledState, Hangfire.Core\",\"EnqueueAt\":" + convertedDateTime + "}", serialized); }
public void OnStateApplied_AddsJobToRetriesSet_IfNewStateIsScheduled() { // Arrange var filter = CreateFilter(); var newState = new ScheduledState(DateTime.UtcNow) { Reason = "Retry attempt ..." }; var applyStateContext = CreatApplyStateContext(newState); // Act filter.OnStateApplied(applyStateContext, _transaction.Object); // Assert _transaction.Verify(t => t.AddToSet("retries", JobId)); }
internal static DateTime?GetCreatedAt(this IState state) { if (state is null) { throw new ArgumentNullException(nameof(state)); } return(state switch { ScheduledState scheduled => scheduled.ScheduledAt, EnqueuedState enqueued => enqueued.EnqueuedAt, ProcessingState processing => processing.StartedAt, SucceededState succeeded => succeeded.SucceededAt, FailedState failed => failed.FailedAt, DeletedState deleted => deleted.DeletedAt, _ => default(DateTime?), });
public void OnStateApplied_DoesNotAddJobToRetriesSet_IfNewStateIsScheduledAndReasonDoesNotMatch() { // Arrange var filter = CreateFilter(); var newState = new ScheduledState(DateTime.UtcNow) { Reason = "Some reason." }; var applyStateContext = CreatApplyStateContext(newState); // Act filter.OnStateApplied(applyStateContext, _transaction.Object); // Assert _transaction.Verify(t => t.AddToSet(It.IsAny <string>(), It.IsAny <string>()), Times.Never); }
/// <summary> /// Schedules an attempt to start a jump. This will be performed in the /// next tick if possible. /// </summary> // TODO: Support early/late jumps so it feels more responsive? public void ScheduleJumpStartAttempt() => this.scheduledJumpState_ = ScheduledState.STARTING;
public void IgnoreExceptions_ReturnsFalse() { var state = new ScheduledState(DateTime.UtcNow); Assert.False(state.IgnoreJobLoadException); }
public void IsFinal_ReturnsFalse() { var state = new ScheduledState(DateTime.UtcNow); Assert.False(state.IsFinal); }
public void Ctor_SetsTheCorrectQueue_WhenProvided() { var state = new ScheduledState(TimeSpan.FromDays(1), "queue_name"); Assert.True(state.QueueName == "queue_name"); }
public void StateName_IsCorrect() { var state = new ScheduledState(DateTime.UtcNow); Assert.Equal(ScheduledState.StateName, state.Name); }
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); }
public void IsFinal_ReturnsFalse() { var state = new ScheduledState(DateTime.UtcNow, EnqueuedState.DefaultQueue); Assert.False(state.IsFinal); }
public void ScheduleDuckStartAttempt() => this.scheduledDuckState_ = ScheduledState.STARTING;
public void ScheduleDuckStopAttempt() => this.scheduledDuckState_ = ScheduledState.STOPPING;
/// <summary> /// Schedules an attempt to stop a jump early. This will be performed in /// the next tick if possible. /// </summary> public void ScheduleJumpStopAttempt() => this.scheduledJumpState_ = ScheduledState.STOPPING;