private static IState ElectState(
            ElectStateContext context,
            IEnumerable <IElectStateFilter> filters)
        {
            var statesToAppend = new List <IState>();

            foreach (var filter in filters)
            {
                var oldState = context.CandidateState;
                filter.OnStateElection(context);

                if (oldState != context.CandidateState)
                {
                    statesToAppend.Add(oldState);
                }
            }

            if (statesToAppend.Count > 0)
            {
                using (var transaction = context.Connection.CreateWriteTransaction())
                {
                    foreach (var state in statesToAppend)
                    {
                        transaction.AddJobState(context.JobId, state);
                    }

                    transaction.Commit();
                }
            }

            return(context.CandidateState);
        }
        public bool ChangeState(StateContext context, IState toState, string oldStateName)
        {
            try
            {
                var filterInfo = GetFilters(context.Job);

                var electStateContext = new ElectStateContext(context, toState, oldStateName);
                var electedState      = ElectState(electStateContext, filterInfo.ElectStateFilters);

                var applyStateContext = new ApplyStateContext(context, electedState, oldStateName);
                ApplyState(applyStateContext, 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"
                };

                var applyStateContext = new ApplyStateContext(context, failedState, oldStateName);

                // We should not use any state changed filters, because
                // some of the could cause an exception.
                ApplyState(applyStateContext, Enumerable.Empty <IApplyStateFilter>());

                // State transition was failed due to exception.
                return(false);
            }
        }
Beispiel #3
0
 public void ElectState(IStorageConnection connection, ElectStateContext context)
 {
     var filterInfo = GetFilters(context.Job);
     foreach (var filter in filterInfo.ElectStateFilters)
     {
         filter.OnStateElection(context);
     }
 }
Beispiel #4
0
        private void ChangeState(StateContext context, IState toState, string oldStateName)
        {
            var electStateContext = new ElectStateContext(context, _connection, this, toState, oldStateName);

            _stateChangeProcess.ElectState(_connection, electStateContext);

            var applyStateContext = new ApplyStateContext(
                context,
                electStateContext.CandidateState,
                oldStateName,
                electStateContext.TraversedStates);

            ApplyState(applyStateContext);
        }
Beispiel #5
0
        public IState ApplyState(ApplyStateContext initialContext)
        {
            var filterInfo   = GetFilters(initialContext.BackgroundJob.Job);
            var electFilters = filterInfo.ElectStateFilters;
            var applyFilters = filterInfo.ApplyStateFilters;

            // Electing a a state
            var electContext = new ElectStateContext(initialContext);

            foreach (var filter in electFilters)
            {
                electContext.Profiler.InvokeMeasured(
                    Tuple.Create(filter, electContext),
                    InvokeOnStateElection,
                    $"OnStateElection for {electContext.BackgroundJob.Id}");
            }

            foreach (var state in electContext.TraversedStates)
            {
                initialContext.Transaction.AddJobState(electContext.BackgroundJob.Id, state);
            }

            // Applying the elected state
            var context = new ApplyStateContext(initialContext.Transaction, electContext)
            {
                JobExpirationTimeout = initialContext.JobExpirationTimeout
            };

            foreach (var filter in applyFilters)
            {
                context.Profiler.InvokeMeasured(
                    Tuple.Create(filter, context),
                    InvokeOnStateUnapplied,
                    $"OnStateUnapplied for {context.BackgroundJob.Id}");
            }

            foreach (var filter in applyFilters)
            {
                context.Profiler.InvokeMeasured(
                    Tuple.Create(filter, context),
                    InvokeOnStateApplied,
                    $"OnStateApplied for {context.BackgroundJob.Id}");
            }

            return(_innerStateMachine.ApplyState(context));
        }
Beispiel #6
0
        /// <summary>
        /// Called by Hangfire when the state of the job changes
        /// </summary>
        ///

        public void OnStateElection(Hangfire.States.ElectStateContext context)
        {
            var enqueuedState = context.CandidateState as Hangfire.States.EnqueuedState;

            if (enqueuedState != null)
            {
                var qn = context.GetJobParameter <string>("QueueName");
                if (!String.IsNullOrWhiteSpace(qn))
                {
                    enqueuedState.Queue = qn;
                }
                else
                {
                    context.SetJobParameter("QueueName", enqueuedState.Queue);
                }
            }
        }
Beispiel #7
0
        public IState ApplyState(ApplyStateContext initialContext)
        {
            var filterInfo   = GetFilters(initialContext.BackgroundJob.Job);
            var electFilters = filterInfo.ElectStateFilters;
            var applyFilters = filterInfo.ApplyStateFilters;

            // Electing a a state
            var electContext = new ElectStateContext(initialContext);

            foreach (var filter in electFilters)
            {
                filter.OnStateElection(electContext);
            }

            foreach (var state in electContext.TraversedStates)
            {
                initialContext.Transaction.AddJobState(electContext.BackgroundJob.Id, state);
            }

            // Applying the elected state
            var context = new ApplyStateContext(initialContext.Transaction, electContext)
            {
                JobExpirationTimeout = initialContext.JobExpirationTimeout
            };

            foreach (var filter in applyFilters)
            {
                filter.OnStateUnapplied(context, context.Transaction);
            }

            foreach (var filter in applyFilters)
            {
                filter.OnStateApplied(context, context.Transaction);
            }

            return(_innerStateMachine.ApplyState(context));
        }
Beispiel #8
0
 public ApplyStateContext(
     [NotNull] IWriteOnlyTransaction transaction,
     [NotNull] ElectStateContext context)
     : this(context.Storage, context.Connection, transaction, context.BackgroundJob, context.CandidateState, context.CurrentState)
 {
 }