Example #1
0
 public void GivenTheEnqueuedState()
 {
     _state = new EnqueuedState
     {
         Reason = "SomeReason"
     };
 }
Example #2
0
 public void GivenTheScheduledStateWithTheDateSetToTomorrow()
 {
     _state = new ScheduledState(DateTime.UtcNow.AddDays(1))
     {
         Reason = "SomeReason"
     };
 }
Example #3
0
 public void GivenTheProcessingState()
 {
     _state = new ProcessingState("TestServer")
     {
         Reason = "SomeReason"
     };
 }
Example #4
0
        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;
            }
        }
Example #5
0
 public void GivenTheFailedState()
 {
     _failedException = new InvalidOperationException("Hello");
     _state = new FailedState(_failedException)
     {
         Reason = "SomeReason"
     };
 }
Example #6
0
        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);
        }
Example #7
0
        /// <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
                }));
        }
Example #9
0
        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;
        }
Example #10
0
        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);
        }
Example #11
0
        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);
        }
Example #12
0
        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)));
        }
Example #17
0
 public void GivenTheSucceededState()
 {
     _state = new SucceededState { Reason = "SomeReason" };
 }