예제 #1
0
        // Save the workflow instance state at the point of persistence with option of locking the instance state if it is shared
        // across multiple runtimes or multiple phase instance updates
        protected override void SaveWorkflowInstanceState(Activity rootActivity, bool unlock)
        {
            // Save the workflow
            Guid contextGuid = (Guid)rootActivity.GetValue(Activity.ActivityContextGuidProperty);

            Console.WriteLine("Saving instance: {0}\n", contextGuid);
            SerializeToFile(
                WorkflowPersistenceService.GetDefaultSerializedForm(rootActivity), contextGuid);

            // See when the next timer (Delay activity) for this workflow will expire
            TimerEventSubscriptionCollection timers       = (TimerEventSubscriptionCollection)rootActivity.GetValue(TimerEventSubscriptionCollection.TimerCollectionProperty);
            TimerEventSubscription           subscription = timers.Peek();

            if (subscription != null)
            {
                // Set a system timer to automatically reload this workflow when its next timer expires
                TimerCallback callback       = new TimerCallback(ReloadWorkflow);
                TimeSpan      timeDifference = subscription.ExpiresAt - DateTime.UtcNow;
                // check to make sure timeDifference is in legal range
                if (timeDifference > FilePersistenceService.MaxInterval)
                {
                    timeDifference = FilePersistenceService.MaxInterval;
                }
                else if (timeDifference < TimeSpan.Zero)
                {
                    timeDifference = TimeSpan.Zero;
                }
                this.instanceTimers.Add(contextGuid, new System.Threading.Timer(
                                            callback,
                                            subscription.WorkflowInstanceId,
                                            timeDifference,
                                            new TimeSpan(-1)));
            }
        }
예제 #2
0
        // Save the workflow instance state at the point of persistence with option of locking the instance state if it is shared
        // across multiple runtimes or multiple phase instance updates
        protected override void SaveWorkflowInstanceState(Activity rootActivity, bool unlock)
        {
            // Save the workflow
            var contextId = (Guid)rootActivity.GetValue(Activity.ActivityContextGuidProperty);

            _instanceStore[contextId] = GetDefaultSerializedForm(rootActivity);

            // See when the next timer (Delay activity) for this workflow will expire
            var timers = (TimerEventSubscriptionCollection)rootActivity.GetValue(TimerEventSubscriptionCollection.TimerCollectionProperty);
            TimerEventSubscription subscription = timers.Peek();

            if (subscription != null)
            {
                // Set a system timer to automatically reload this workflow when its next timer expires
                TimeSpan timeDifference = subscription.ExpiresAt - DateTime.UtcNow;

                // check to make sure timeDifference is in legal range
                if (timeDifference > MaxInterval)
                {
                    timeDifference = MaxInterval;
                }
                else if (timeDifference < TimeSpan.Zero)
                {
                    timeDifference = TimeSpan.Zero;
                }

                _instanceTimers.Add(contextId, new Timer(
                                        ReloadWorkflow,
                                        subscription.WorkflowInstanceId,
                                        timeDifference,
                                        new TimeSpan(-1)));
            }
        }
예제 #3
0
        void IEventActivity.Subscribe(ActivityExecutionContext parentContext, IActivityEventListener <QueueEventArgs> parentEventHandler)
        {
            if (parentContext == null)
            {
                throw new ArgumentNullException("parentContext");
            }
            if (parentEventHandler == null)
            {
                throw new ArgumentNullException("parentEventHandler");
            }
            this.IsInEventActivityMode = true;
            base.RaiseEvent(InitializeTimeoutDurationEvent, this, EventArgs.Empty);
            TimeSpan timeoutDuration         = this.TimeoutDuration;
            DateTime expiresAt               = DateTime.UtcNow + timeoutDuration;
            WorkflowQueuingService service   = parentContext.GetService <WorkflowQueuingService>();
            IComparable            queueName = ((IEventActivity)this).QueueName;
            TimerEventSubscription item      = new TimerEventSubscription((Guid)queueName, base.WorkflowInstanceId, expiresAt);

            service.CreateWorkflowQueue(queueName, false).RegisterForQueueItemAvailable(parentEventHandler, base.QualifiedName);
            this.SubscriptionID = item.SubscriptionId;
            Activity parent = this;

            while (parent.Parent != null)
            {
                parent = parent.Parent;
            }
            ((TimerEventSubscriptionCollection)parent.GetValue(TimerEventSubscriptionCollection.TimerCollectionProperty)).Add(item);
        }
예제 #4
0
        /// <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;
            }
        }
예제 #5
0
        public void Constructor2()
        {
            TimerEventSubscription timer;
            Guid     workflowInstanceId = Guid.NewGuid();
            DateTime expiresAt          = DateTime.Today;

            timer = new TimerEventSubscription(workflowInstanceId, expiresAt);
            Assert.AreEqual(workflowInstanceId, timer.WorkflowInstanceId, "C1#1");
            Assert.AreEqual(timer.SubscriptionId, timer.QueueName, "C1#2");
        }
        public void TestCollection()
        {
            TimerEventSubscriptionCollection col;

            // There is no public constructor for TimerEventSubscriptionCollection
            col = (TimerEventSubscriptionCollection)Activator.CreateInstance
                      (typeof(TimerEventSubscriptionCollection),
                      BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public,
                      null, null, null);

            TimerEventSubscription event1 = new TimerEventSubscription(Guid.NewGuid(),
                                                                       new DateTime(2006, 07, 30));

            TimerEventSubscription event2 = new TimerEventSubscription(Guid.NewGuid(),
                                                                       new DateTime(2006, 07, 28));

            TimerEventSubscription event3 = new TimerEventSubscription(Guid.NewGuid(),
                                                                       new DateTime(2006, 08, 28));

            TimerEventSubscription event4 = new TimerEventSubscription(Guid.NewGuid(),
                                                                       new DateTime(2007, 08, 28));

            TimerEventSubscription event5 = new TimerEventSubscription(Guid.NewGuid(),
                                                                       new DateTime(2006, 05, 28));

            TimerEventSubscription event6 = new TimerEventSubscription(Guid.NewGuid(),
                                                                       new DateTime(2008, 02, 28));

            TimerEventSubscription event7 = new TimerEventSubscription(Guid.NewGuid(),
                                                                       new DateTime(2005, 05, 28));

            col.Add(event1);
            col.Add(event2);
            col.Add(event3);
            col.Add(event4);
            col.Add(event5);
            col.Add(event6);
            col.Add(event7);

            Assert.AreEqual(event7.ExpiresAt, col.Peek().ExpiresAt, "C1#1");
            col.Remove(col.Peek());
            Assert.AreEqual(event5.ExpiresAt, col.Peek().ExpiresAt, "C1#2");
            col.Remove(col.Peek());
            Assert.AreEqual(event2.ExpiresAt, col.Peek().ExpiresAt, "C1#3");
            col.Remove(col.Peek());
            Assert.AreEqual(event1.ExpiresAt, col.Peek().ExpiresAt, "C1#4");
            col.Remove(col.Peek());
            Assert.AreEqual(event3.ExpiresAt, col.Peek().ExpiresAt, "C1#5");
            col.Remove(col.Peek());
            Assert.AreEqual(event4.ExpiresAt, col.Peek().ExpiresAt, "C1#6");
        }
예제 #7
0
        protected IComparable SetTimer(ActivityExecutionContext executionContext, DateTime expiresAt)
        {
                #if RUNTIME_DEP
            TimerEventSubscription te;
            WorkflowQueue          queue;

            te = new TimerEventSubscription(executionContext.ExecutionContextManager.Workflow.InstanceId,
                                            expiresAt);

            WorkflowQueuingService qService = executionContext.GetService <WorkflowQueuingService> ();
            queue = qService.CreateWorkflowQueue(te.QueueName, true);
            queue.QueueItemArrived += OnQueueTimerItemArrived;
            executionContext.ExecutionContextManager.Workflow.TimerEventSubscriptionCollection.Add(te);
            return(te.QueueName);
                #else
            return(null);
                #endif
        }
예제 #8
0
        void IEventActivity.Subscribe(ActivityExecutionContext parentContext, IActivityEventListener <QueueEventArgs> parentEventHandler)
        {
            if (parentContext == null)
            {
                throw new ArgumentNullException("parentContext");
            }
            if (parentEventHandler == null)
            {
                throw new ArgumentNullException("parentEventHandler");
            }

            this.IsInEventActivityMode = true;

            base.RaiseEvent(DelayActivity.InitializeTimeoutDurationEvent, this, EventArgs.Empty);
            TimeSpan timeSpan = this.TimeoutDuration;
            DateTime timeOut  = DateTime.UtcNow + timeSpan;

            WorkflowQueuingService qService = parentContext.GetService <WorkflowQueuingService>();

            IComparable            queueName = ((IEventActivity)this).QueueName;
            TimerEventSubscription timerSub  = new TimerEventSubscription((Guid)queueName, this.WorkflowInstanceId, timeOut);
            WorkflowQueue          queue     = qService.CreateWorkflowQueue(queueName, false);

            queue.RegisterForQueueItemAvailable(parentEventHandler, this.QualifiedName);
            this.SubscriptionID = timerSub.SubscriptionId;

            Activity root = this;

            while (root.Parent != null)
            {
                root = root.Parent;
            }

            TimerEventSubscriptionCollection timers = (TimerEventSubscriptionCollection)root.GetValue(TimerEventSubscriptionCollection.TimerCollectionProperty);

            Debug.Assert(timers != null, "TimerEventSubscriptionCollection on root activity should never be null, but it was");
            timers.Add(timerSub);
        }
        protected internal override void SaveWorkflowInstanceState(Activity rootActivity, bool unlock)
        {
            if (rootActivity == null)
            {
                throw new ArgumentNullException("rootActivity");
            }
            WorkflowStatus  workflowStatus         = WorkflowPersistenceService.GetWorkflowStatus(rootActivity);
            bool            isBlocked              = WorkflowPersistenceService.GetIsBlocked(rootActivity);
            string          suspendOrTerminateInfo = WorkflowPersistenceService.GetSuspendOrTerminateInfo(rootActivity);
            Guid            guid     = (Guid)rootActivity.GetValue(Activity.ActivityContextGuidProperty);
            PendingWorkItem workItem = new PendingWorkItem {
                Type       = PendingWorkItem.ItemType.Instance,
                InstanceId = WorkflowEnvironment.WorkflowInstanceId
            };

            if ((workflowStatus != WorkflowStatus.Completed) && (workflowStatus != WorkflowStatus.Terminated))
            {
                workItem.SerializedActivity = WorkflowPersistenceService.GetDefaultSerializedForm(rootActivity);
            }
            else
            {
                workItem.SerializedActivity = new byte[0];
            }
            workItem.Status   = (int)workflowStatus;
            workItem.Blocked  = isBlocked ? 1 : 0;
            workItem.Info     = suspendOrTerminateInfo;
            workItem.StateId  = guid;
            workItem.Unlocked = unlock;
            TimerEventSubscription subscription = ((TimerEventSubscriptionCollection)rootActivity.GetValue(TimerEventSubscriptionCollection.TimerCollectionProperty)).Peek();

            workItem.NextTimer = (subscription == null) ? SqlDateTime.MaxValue : subscription.ExpiresAt;
            if (workItem.Info == null)
            {
                workItem.Info = "";
            }
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "SqlWorkflowPersistenceService({4}):Committing instance {0}, Blocked={1}, Unlocked={2}, NextTimer={3}", new object[] { guid.ToString(), workItem.Blocked, workItem.Unlocked, workItem.NextTimer.Value.ToLocalTime(), this._serviceInstanceId.ToString() });
            WorkflowEnvironment.WorkBatch.Add(this, workItem);
        }