Exemple #1
0
        ///<summary>
        ///Commits the list of work items by using the specified <see cref="T:System.Transactions.Transaction"></see> object.
        ///</summary>
        ///
        ///<param name="items">The work items to be committed.</param>
        ///<param name="transaction">The <see cref="T:System.Transactions.Transaction"></see> associated with the pending work.</param>
        public void Commit(Transaction transaction, ICollection items)
        {
            TraceHelper.Trace();

            if (transaction == null)
            {
                throw new ArgumentNullException("transaction");
            }

            if (items == null)
            {
                throw new ArgumentNullException("items");
            }

            try
            {
                using (IPersistenceResourceAccessor resourceAccessor = CreateAccessor(_resourceProvider, transaction))
                {
                    foreach (PendingWorkItem item in items)
                    {
                        switch (item.Type)
                        {
                        case PendingWorkItem.ItemType.Instance:
                            resourceAccessor.InsertInstanceState(item,
                                                                 _serviceId, ownershipTimeout);

                            continue;

                        case PendingWorkItem.ItemType.CompletedScope:
                            resourceAccessor.InsertCompletedScope(
                                item.InstanceId, item.StateId,
                                item.SerialisedActivity);

                            continue;

                        case PendingWorkItem.ItemType.UnlockWorkflow:
                            resourceAccessor.UnlockInstanceState(
                                item.InstanceId, _serviceId);

                            continue;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                String errorMessage = RM.Get_Error_PersistenceServiceException(e.ToString());

                TraceHelper.Trace(errorMessage);

                PersistenceException persistenceException =
                    new PersistenceException(errorMessage, e);

                RaiseServicesExceptionNotHandledEvent(
                    persistenceException,
                    Guid.Empty);

                throw persistenceException;
            }
        }
Exemple #2
0
        ///<summary>
        ///Called when the transaction has completed.
        ///</summary>
        ///
        ///<param name="items">An <see cref="T:System.Collections.ICollection"></see> of work items.</param>
        ///<param name="succeeded">true if the transaction succeeded; otherwise, false.</param>
        public void Complete(Boolean succeeded, ICollection items)
        {
            TraceHelper.Trace();

            try
            {
                if (succeeded)
                {
                    foreach (PendingWorkItem item in items)
                    {
                        if (item.Type == PendingWorkItem.ItemType.Instance && item.NextTimer != null)
                        {
                            _smartTimer.Update(item.NextTimer.Value);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                String errorMessage = RM.Get_Error_PersistenceServiceException(e.ToString());

                TraceHelper.Trace(errorMessage);

                PersistenceException persistenceException
                    = new PersistenceException(errorMessage, e);

                RaiseServicesExceptionNotHandledEvent(
                    persistenceException, Guid.Empty);

                throw persistenceException;
            }
        }
Exemple #3
0
        /// <summary>
        /// Persist a completed scope to the persistence store.
        /// </summary>
        /// <param name="activity">
        /// The completed scope to pesist.
        /// </param>
        protected override void SaveCompletedContextActivity(Activity activity)
        {
            TraceHelper.Trace();

            try
            {
                PendingWorkItem workItem = new PendingWorkItem();
                workItem.Type = PendingWorkItem.ItemType.CompletedScope;
                workItem.SerialisedActivity = GetDefaultSerializedForm(activity);
                workItem.InstanceId         = WorkflowEnvironment.WorkflowInstanceId;
                workItem.StateId            = (Guid)activity.GetValue(
                    Activity.ActivityContextGuidProperty);

                WorkflowEnvironment.WorkBatch.Add(this, workItem);
            }
            catch (Exception e)
            {
                String errorMessage = RM.Get_Error_PersistenceServiceException(e.ToString());

                TraceHelper.Trace(errorMessage);

                PersistenceException persistenceException =
                    new PersistenceException(errorMessage, e);

                RaiseServicesExceptionNotHandledEvent(
                    persistenceException,
                    WorkflowEnvironment.WorkflowInstanceId);

                throw persistenceException;
            }
        }
Exemple #4
0
        /// <summary>
        /// Load a completed scope from the persistence store.
        /// </summary>
        /// <param name="scopeId">
        /// <see cref="Guid" /> representing the unique identifier of the completed scope.
        /// </param>
        /// <param name="outerActivity">
        /// The activity in which to load the completed scope into.
        /// </param>
        protected override Activity LoadCompletedContextActivity(Guid scopeId, Activity outerActivity)
        {
            TraceHelper.Trace();

            Activity contextActivity;

            try
            {
                using (IPersistenceResourceAccessor resourceAccessor = CreateAccessor(_resourceProvider))
                {
                    byte[] instanceState = resourceAccessor.RetrieveCompletedScope(scopeId);

                    contextActivity = RestoreFromDefaultSerializedForm(instanceState, outerActivity);
                }
            }
            catch (Exception e)
            {
                String errorMessage = RM.Get_Error_PersistenceServiceException(e.ToString());

                TraceHelper.Trace(errorMessage);

                PersistenceException persistenceException =
                    new PersistenceException(errorMessage, e);

                RaiseServicesExceptionNotHandledEvent(
                    persistenceException,
                    WorkflowEnvironment.WorkflowInstanceId);

                throw persistenceException;
            }

            return(contextActivity);
        }
Exemple #5
0
        /// <summary>
        /// Unlock a workflow instance.
        /// </summary>
        /// <param name="rootActivity">
        /// The root activity of the workflow instance.
        /// </param>
        protected override void UnlockWorkflowInstanceState(Activity rootActivity)
        {
            TraceHelper.Trace();

            try
            {
                PendingWorkItem workItem = new PendingWorkItem();
                workItem.Type       = PendingWorkItem.ItemType.UnlockWorkflow;
                workItem.InstanceId = WorkflowEnvironment.WorkflowInstanceId;

                WorkflowEnvironment.WorkBatch.Add(this, workItem);
            }
            catch (Exception e)
            {
                String errorMessage = RM.Get_Error_PersistenceServiceException(e.ToString());

                TraceHelper.Trace(errorMessage);

                PersistenceException persistenceException =
                    new PersistenceException(errorMessage, e);

                RaiseServicesExceptionNotHandledEvent(
                    persistenceException,
                    WorkflowEnvironment.WorkflowInstanceId);

                throw persistenceException;
            }
        }
Exemple #6
0
        ///<summary>
        /// Load the specified workflow instance into memory from the
        /// persistence store.
        ///</summary>
        ///<param name="instanceId">
        /// The <see cref="T:System.Guid"></see> of the root activity of the workflow instance.
        /// </param>
        protected override Activity LoadWorkflowInstanceState(Guid instanceId)
        {
            TraceHelper.Trace();

            Activity rootActivity;

            try
            {
                using (IPersistenceResourceAccessor resourceAccessor = CreateAccessor(_resourceProvider))
                {
                    byte[] instanceState = resourceAccessor.RetrieveInstanceState(
                        instanceId, _serviceId, ownershipTimeout);

                    rootActivity = RestoreFromDefaultSerializedForm(instanceState, null);
                }
            }
            catch (Exception e)
            {
                String errorMessage = RM.Get_Error_PersistenceServiceException(e.ToString());

                TraceHelper.Trace(errorMessage);

                PersistenceException persistenceException =
                    new PersistenceException(errorMessage, e);

                RaiseServicesExceptionNotHandledEvent(
                    persistenceException, instanceId);

                throw persistenceException;
            }

            return(rootActivity);
        }
Exemple #7
0
        /// <summary>
        /// Kick-off the timer to check for workflows with expired timers,
        /// and recover running workflow instances.
        /// </summary>
        protected override void OnStarted()
        {
            TraceHelper.Trace();

            try
            {
                base.OnStarted();

                if (_loadInterval > TimeSpan.Zero)
                {
                    lock (_timerLock)
                    {
                        _smartTimer = new SmartTimer(
                            loadWorkflowsWithExpiredTimers,
                            null, _loadInterval, _loadInterval);
                    }
                }

                recoverRunningWorkflows();
            }
            catch (Exception e)
            {
                String errorMessage = RM.Get_Error_PersistenceServiceException(e.ToString());

                TraceHelper.Trace(errorMessage);

                PersistenceException persistenceException =
                    new PersistenceException(errorMessage, e);

                RaiseServicesExceptionNotHandledEvent(
                    persistenceException, Guid.Empty);

                throw persistenceException;
            }
        }
Exemple #8
0
        /// <summary>
        /// Perform shutdown duties associated with this persistence service.
        /// <remarks>
        /// This implementation disposes the internal <see cref="SmartTimer" />
        /// responsible for loading expired workflows into memory.
        /// </remarks>
        /// </summary>
        protected override void Stop()
        {
            TraceHelper.Trace();

            try
            {
                base.Stop();

                lock (_timerLock)
                {
                    if (_smartTimer != null)
                    {
                        _smartTimer.Dispose();
                        _smartTimer = null;
                    }
                }
            }
            catch (Exception e)
            {
                String errorMessage = RM.Get_Error_PersistenceServiceException(e.ToString());

                TraceHelper.Trace(errorMessage);

                PersistenceException persistenceException =
                    new PersistenceException(errorMessage, e);

                RaiseServicesExceptionNotHandledEvent(
                    persistenceException, Guid.Empty);

                throw persistenceException;
            }
        }
Exemple #9
0
        /// <summary>
        /// Perform startup duties associated with this persistence service.
        /// <remarks>
        /// This implementation calls a virtual method to create a single
        /// resource provider for this persistence service.
        /// </remarks>
        /// </summary>
        protected override void Start()
        {
            TraceHelper.Trace();

            try
            {
                // retrieve the active resource provider
                _resourceProvider = CreateResourceProvider();

                base.Start();
            }
            catch (Exception e)
            {
                String errorMessage = RM.Get_Error_PersistenceServiceException(e.ToString());

                TraceHelper.Trace(errorMessage);

                PersistenceException persistenceException =
                    new PersistenceException(errorMessage, e);

                RaiseServicesExceptionNotHandledEvent(
                    persistenceException, Guid.Empty);

                throw persistenceException;
            }
        }
        ///<summary>
        ///Called when the transaction has completed.
        ///</summary>
        ///
        ///<param name="items">An <see cref="T:System.Collections.ICollection"></see> of work items.</param>
        ///<param name="succeeded">true if the transaction succeeded; otherwise, false.</param>
        public void Complete(bool succeeded, ICollection items)
        {
            TraceHelper.Trace();

            try
            {
                if (succeeded)
                {
                    foreach (PendingWorkItem item in items)
                    {
                        if (item.Type == PendingWorkItem.ItemType.Instance && item.NextTimer != null)
                        {
                            this.smartTimer.Update(item.NextTimer.Value);
                        }
                    }
                    WfLogHelper.WriteLog("持久化提交事务Complete完成......");
                }
            }
            catch (Exception e)
            {
                WfLogHelper.WriteLog("持久化Complete务发生异常:" + e.ToString());
                string errorMessage = RM.Get_Error_PersistenceServiceException(e.ToString());

                TraceHelper.Trace(errorMessage);

                PersistenceException persistenceException
                    = new PersistenceException(errorMessage, e);

                base.RaiseServicesExceptionNotHandledEvent(
                    persistenceException, Guid.Empty);

                throw persistenceException;
            }
        }
        /// <summary>
        /// Persist a workflow instance to the persistence store.
        /// </summary>
        /// <param name="rootActivity">
        /// Root activity of the workflow instance.
        /// </param>
        /// <param name="unlock">
        /// Indicates whether to unlock the instance when complete.
        /// </param>
        protected override void SaveWorkflowInstanceState(Activity rootActivity, bool unlock)
        {
            TraceHelper.Trace();

            try
            {
                if (rootActivity == null)
                {
                    throw new ArgumentNullException("rootActivity");
                }

                PendingWorkItem workItem = new PendingWorkItem();
                workItem.Status     = GetWorkflowStatus(rootActivity);
                workItem.IsBlocked  = GetIsBlocked(rootActivity);
                workItem.Info       = GetSuspendOrTerminateInfo(rootActivity);
                workItem.StateId    = (Guid)rootActivity.GetValue(Activity.ActivityContextGuidProperty);
                workItem.Type       = PendingWorkItem.ItemType.Instance;
                workItem.InstanceId = WorkflowEnvironment.WorkflowInstanceId;
                workItem.Unlock     = unlock;
                if (workItem.Status != WorkflowStatus.Completed && workItem.Status != WorkflowStatus.Terminated)
                {
                    workItem.SerialisedActivity = GetDefaultSerializedForm(rootActivity);
                }
                else
                {
                    workItem.SerialisedActivity = new byte[0];
                }

                TimerEventSubscription timerEventSubscription =
                    ((TimerEventSubscriptionCollection)rootActivity.GetValue(
                         TimerEventSubscriptionCollection.TimerCollectionProperty)).Peek();

                if (timerEventSubscription == null)
                {
                    workItem.NextTimer = null;
                }
                else
                {
                    workItem.NextTimer = timerEventSubscription.ExpiresAt;
                }

                WorkflowEnvironment.WorkBatch.Add(this, workItem);
            }
            catch (Exception e)
            {
                WfLogHelper.WriteLog("持久化SaveWorkflowInstanceState发生异常:" + e.ToString());
                string errorMessage = RM.Get_Error_PersistenceServiceException(e.ToString());

                TraceHelper.Trace(errorMessage);

                PersistenceException persistenceException =
                    new PersistenceException(errorMessage, e);

                base.RaiseServicesExceptionNotHandledEvent(
                    persistenceException,
                    WorkflowEnvironment.WorkflowInstanceId);

                throw persistenceException;
            }
        }
        /// <summary>
        /// Retrieve instance state from the persistence store.
        /// </summary>
        /// <param name="instanceId"></param>
        /// <param name="ownerId"></param>
        /// <param name="ownedUntil"></param>
        /// <returns></returns>
        public byte[] RetrieveInstanceState(Guid instanceId, Guid ownerId, DateTime ownedUntil)
        {
            byte[] instanceState = null;

            using (DbCommand dbCommand = CreateCommand(nameResolver.ResolveCommandName(PersistenceCommandName.RetrieveInstanceState), CommandType.StoredProcedure))
            {
                string instanceParameter = nameResolver.ResolveParameterName(
                    PersistenceCommandName.InsertInstanceState,
                    PersistenceParameterName.InstanceId);

                string resultParameter = nameResolver.ResolveParameterName(
                    PersistenceCommandName.InsertInstanceState,
                    PersistenceParameterName.Result);

                AddParameter(dbCommand, instanceParameter, instanceId, AdoDbType.Guid);

                AddParameter(dbCommand, nameResolver.ResolveParameterName(
                    PersistenceCommandName.RetrieveInstanceState,
                    PersistenceParameterName.OwnerId), ownerId, AdoDbType.Guid);

                AddParameter(dbCommand, nameResolver.ResolveParameterName(
                    PersistenceCommandName.RetrieveInstanceState,
                    PersistenceParameterName.OwnedUntil), ownedUntil, AdoDbType.DateTime);

                AddParameter(dbCommand, resultParameter,
                    AdoDbType.Int32, ParameterDirection.Output);

                AddParameter(dbCommand, nameResolver.ResolveParameterName(
                    PersistenceCommandName.RetrieveInstanceState,
                    PersistenceParameterName.CurrentOwnerId), AdoDbType.Guid,
                    ParameterDirection.Output);

                AddParameter(dbCommand, nameResolver.ResolveParameterName(
                    PersistenceCommandName.RetrieveInstanceState,
                    PersistenceParameterName.State), AdoDbType.Cursor,
                    ParameterDirection.Output);

                int? result;
                using (IDataReader dataReader = dbCommand.ExecuteReader())
                {
                    if (dataReader.Read())
                        instanceState = (byte[])valueReader.GetValue(dataReader, 0);

                    result = valueReader.GetNullableInt32(dbCommand, resultParameter);
                }

                if (instanceState == null && result > 0)
                {
                    // workflow could not be found
                    PersistenceException e = new PersistenceException(
                        RM.Get_Error_InstanceCouldNotBeLoaded(instanceId));

                    e.Data["WorkflowNotFound"] = true;
                    Tracer.Debug("����ʵ��״̬ public byte[] RetrieveInstanceState(" + instanceId + ", " + ownerId + ", " + ownedUntil + ")�����쳣:" + e.ToString());
                    throw e;
                }
                else
                    checkResult(dbCommand, resultParameter, instanceParameter);
            }

            return instanceState;
        }