public void GivenTheEnqueuedState() { _state = new EnqueuedState { Reason = "SomeReason" }; }
public void GivenTheScheduledStateWithTheDateSetToTomorrow() { _state = new ScheduledState(DateTime.UtcNow.AddDays(1)) { Reason = "SomeReason" }; }
public void GivenTheProcessingState() { _state = new ProcessingState("TestServer") { Reason = "SomeReason" }; }
public bool TryToChangeState( string jobId, State toState, string[] fromStates) { if (jobId == null) throw new ArgumentNullException("jobId"); if (toState == null) throw new ArgumentNullException("toState"); if (fromStates == null) throw new ArgumentNullException("fromStates"); // To ensure that job state will be changed only from one of the // specified states, we need to ensure that other users/workers // are not able to change the state of the job during the // execution of this method. To guarantee this behavior, we are // using distributed application locks and rely on fact, that // any state transitions will be made only within a such lock. using (_connection.AcquireJobLock(jobId)) { var jobData = _connection.GetJobStateAndInvocationData(jobId); if (jobData == null) { // The job does not exist. This may happen, because not // all storage backends support foreign keys. return false; } if (!fromStates.Contains(jobData.State, StringComparer.OrdinalIgnoreCase)) { return false; } MethodData methodData = null; bool loadSucceeded = true; try { methodData = MethodData.Deserialize(jobData.InvocationData); } catch (JobLoadException ex) { // If the job type could not be loaded, we are unable to // load corresponding filters, unable to process the job // and sometimes unable to change its state (the enqueued // state depends on the type of a job). toState = new FailedState(ex) { Reason = String.Format( "Could not change the state of the job '{0}' to the '{1}'. See the inner exception for details.", toState.Name, jobId) }; loadSucceeded = false; } var context = new StateContext(jobId, methodData); var stateChanged = ChangeState(context, toState, jobData.State); return loadSucceeded && stateChanged; } }
public void GivenTheFailedState() { _failedException = new InvalidOperationException("Hello"); _state = new FailedState(_failedException) { Reason = "SomeReason" }; }
public ApplyStateContext( IStorageConnection connection, StateContext context, State newState, string oldStateName) : base(context) { if (connection == null) throw new ArgumentNullException("connection"); _connection = connection; OldStateName = oldStateName; NewState = newState; JobExpirationTimeout = TimeSpan.FromDays(1); }
/// <inheritdoc /> public string Create(Job job, State state) { if (job == null) throw new ArgumentNullException("job"); if (state == null) throw new ArgumentNullException("state"); try { var context = new CreateContext(_connection, job, state); _process.Run(context); return context.JobId; } catch (Exception ex) { throw new CreateJobFailedException("Job creation process has bee failed. See inner exception for details", ex); } }
public void SetJobState(string jobId, State state) { const string addAndSetStateSql = @" insert into HangFire.State (JobId, Name, Reason, CreatedAt, Data) values (@jobId, @name, @reason, @createdAt, @data); update HangFire.Job set StateId = SCOPE_IDENTITY(), StateName = @name where Id = @id;"; QueueCommand(x => x.Execute( addAndSetStateSql, new { jobId = jobId, name = state.Name, reason = state.Reason, createdAt = DateTime.UtcNow, data = JobHelper.ToJson(state.Serialize()), id = jobId })); }
public string CreateInState( Job job, IDictionary<string, string> parameters, State state) { if (job == null) throw new ArgumentNullException("job"); if (parameters == null) throw new ArgumentNullException("parameters"); if (state == null) throw new ArgumentNullException("state"); var invocationData = job.MethodData.Serialize(); var jobId = _connection.CreateExpiredJob( invocationData, job.Arguments.ToArray(), parameters, TimeSpan.FromHours(1)); var context = new StateContext(jobId, job.MethodData); ChangeState(context, state, null); return jobId; }
internal virtual void ApplyState( StateContext stateContext, State electedState, string oldStateName, IEnumerable<IApplyStateFilter> filters) { var context = new ApplyStateContext( _connection, stateContext, electedState, oldStateName); context.ApplyState(GetHandlers(), filters); }
internal virtual State ElectState( StateContext stateContext, State toState, string fromStateName, IEnumerable<IElectStateFilter> filters) { var context = new ElectStateContext( stateContext, toState, fromStateName, _connection); return context.ElectState(filters); }
internal virtual bool ChangeState(StateContext context, State toState, string oldStateName) { try { var filterInfo = GetFilters(context.MethodData); var electedState = ElectState(context, toState, oldStateName, filterInfo.ElectStateFilters); ApplyState(context, electedState, oldStateName, filterInfo.ApplyStateFilters); // State transition was succeeded. return true; } catch (Exception ex) { var failedState = new FailedState(ex) { Reason = "An exception occurred during the transition of job's state" }; // We should not use any state changed filters, because // some of the could cause an exception. ApplyState(context, failedState, oldStateName, Enumerable.Empty<IApplyStateFilter>()); // State transition was failed due to exception. return false; } }
public TestStateChangingFilter(string name, IList<string> results, State changeState = null) { _name = name; _results = results; _changeState = changeState; }
public void SetJobState(string jobId, State state) { _transaction.QueueCommand(x => x.SetEntryInHash( String.Format(RedisStorage.Prefix + "job:{0}", jobId), "State", state.Name)); _transaction.QueueCommand(x => x.RemoveEntry( String.Format(RedisStorage.Prefix + "job:{0}:state", jobId))); // Redis does not provide repeatable read functionality, // so job state might be changed between reads of the job // state itself and a data of the state. In monitoring API // we don't show state data when data.State !== job.State. var storedData = new Dictionary<string, string>(state.Serialize()); storedData.Add("State", state.Name); if (state.Reason != null) { storedData.Add("Reason", state.Reason); } _transaction.QueueCommand(x => x.SetRangeInHash( String.Format(RedisStorage.Prefix + "job:{0}:state", jobId), storedData)); AddJobState(jobId, state); }
public void AddJobState(string jobId, State state) { const string addStateSql = @" insert into HangFire.State (JobId, Name, Reason, CreatedAt, Data) values (@jobId, @name, @reason, @createdAt, @data)"; QueueCommand(x => x.Execute( addStateSql, new { jobId = jobId, name = state.Name, reason = state.Reason, createdAt = DateTime.UtcNow, data = JobHelper.ToJson(state.Serialize()) })); }
public void AddJobState(string jobId, State state) { // We are storing some more information in the same key, // let's add it. var storedData = new Dictionary<string, string>(state.Serialize()); storedData.Add("State", state.Name); storedData.Add("Reason", state.Reason); storedData.Add("CreatedAt", JobHelper.ToStringTimestamp(DateTime.UtcNow)); _transaction.QueueCommand(x => x.EnqueueItemOnList( String.Format(RedisStorage.Prefix + "job:{0}:history", jobId), JobHelper.ToJson(storedData))); }
public void GivenTheSucceededState() { _state = new SucceededState { Reason = "SomeReason" }; }