internal WorkflowInstance (Guid guid, WorkflowRuntime runtime, Activity root_activity) { this.guid = guid; this.runtime = runtime; this.root_activity = root_activity; subscription_collection = new TimerEventSubscriptionCollection (); queuing_service = new WorkflowQueuingService (); }
// inner Q service constructor internal WorkflowQueuingService(WorkflowQueuingService copyFromQueuingService) { this.rootQueuingService = copyFromQueuingService; this.rootWorkflowExecutor = copyFromQueuingService.rootWorkflowExecutor; this.rootWorkflowExecutor.RootActivity.SetValue(WorkflowQueuingService.PendingMessagesProperty, this.pendingQueueState.Messages); this.persistedQueueStates = new Dictionary<IComparable, EventQueueState>(); this.rootWorkflowExecutor.RootActivity.SetValue(WorkflowQueuingService.LocalPersistedQueueStatesProperty, this.persistedQueueStates); SubscribeForRootMessageDelivery(); }
private void AddMessageArrivedEventHandler(WorkflowQueuingService handler) { lock (this.SyncRoot) { if (this.messageArrivalEventHandlers == null) { this.messageArrivalEventHandlers = new List<WorkflowQueuingService>(); } this.messageArrivalEventHandlers.Add(handler); } }
internal static object DequeueMessage(IComparable queueId, WorkflowQueuingService queueSvcs, Activity activity, out WorkflowQueue queue) { object message = null; queue = queueSvcs.GetWorkflowQueue(queueId); if (queue.Count != 0) { message = queue.Dequeue(); if (message == null) throw new ArgumentException(SR.GetString(SR.Error_InvalidEventMessage, activity.QualifiedName)); } return message; }
internal static object DequeueMessage(IComparable queueId, WorkflowQueuingService queueSvcs, Activity activity, out WorkflowQueue queue) { object obj2 = null; queue = queueSvcs.GetWorkflowQueue(queueId); if (queue.Count != 0) { obj2 = queue.Dequeue(); if (obj2 == null) { throw new ArgumentException(SR.GetString("Error_InvalidEventMessage", new object[] { activity.QualifiedName })); } } return obj2; }
protected override void OnActivityExecutionContextLoad(IServiceProvider provider) { Logger.Instance.WriteMethodEntry(EventIdentifier.AsyncUpdateResourceOnActivityExecutionContextLoad); try { Logger.SetContextItem(this, this.WorkflowInstanceId); base.OnActivityExecutionContextLoad(provider); // Load the data access service via reflection Assembly assembly = Assembly.GetAssembly(typeof(UpdateResourceActivity)); const string TypeName = "Microsoft.ResourceManagement.Workflow.Runtime.DataAccessService"; this.dataAccessServiceType = assembly.GetType(TypeName); if (this.dataAccessServiceType == null) { throw Logger.Instance.ReportError(new WorkflowActivityLibraryException(Messages.DefinitionsConverter_NullOrEmptyDefinitionsTableError, TypeName)); } this.dataAccessService = provider.GetService(this.dataAccessServiceType); this.queuingService = (WorkflowQueuingService)provider.GetService(typeof(WorkflowQueuingService)); } finally { Logger.Instance.WriteMethodExit(EventIdentifier.AsyncUpdateResourceOnActivityExecutionContextLoad); } }
internal WorkflowQueue (WorkflowQueuingService service, IComparable queue_name) { queue = new Queue <object> (); this.service = service; this.queue_name = queue_name; }
// Used to recreate the root schedule executor from its persisted state private void ReloadHelper(Activity rootActivity) { // assign activity state this.rootActivity = rootActivity; this.InstanceId = (Guid)rootActivity.GetValue(WorkflowInstanceIdProperty); // set workflow executor this.rootActivity.SetValue(WorkflowExecutor.WorkflowExecutorProperty, this); this._schedulerLock = LockFactory.CreateWorkflowSchedulerLock(this.InstanceId); this.schedulingContext = new Scheduler(this, false); this.qService = new WorkflowQueuingService(this); WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor: Loading instance {0}", this.InstanceIdString); DiagnosticStackTrace("load request"); using (new ServiceEnvironment(this.rootActivity)) { // check if this instance can be loaded switch (this.WorkflowStatus) { case WorkflowStatus.Completed: case WorkflowStatus.Terminated: WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Runtime: WorkflowExecutor: attempt to load a completed/terminated instance: {0}", this.InstanceIdString); throw new InvalidOperationException( ExecutionStringManager.InvalidAttemptToLoad); default: break; } // new nonSerialized members _resourceManager = new VolatileResourceManager(); _runtime = _workflowInstance.WorkflowRuntime; // register all dynamic activities for loading Queue<Activity> dynamicActivitiesQueue = new Queue<Activity>(); dynamicActivitiesQueue.Enqueue(this.rootActivity); while (dynamicActivitiesQueue.Count > 0) { Activity dynamicActivity = dynamicActivitiesQueue.Dequeue(); ((IDependencyObjectAccessor)dynamicActivity).InitializeInstanceForRuntime(this); this.RegisterDynamicActivity(dynamicActivity, true); IList<Activity> nestedDynamicActivities = (IList<Activity>)dynamicActivity.GetValue(Activity.ActiveExecutionContextsProperty); if (nestedDynamicActivities != null) { foreach (Activity nestedDynamicActivity in nestedDynamicActivities) dynamicActivitiesQueue.Enqueue(nestedDynamicActivity); } } } this.isInstanceIdle = (bool)this.rootActivity.GetValue(IsIdleProperty); RefreshWorkflowDefinition(); }
// Initialize for the root schedule internal void Initialize(Activity rootActivity, WorkflowExecutor invokerExec, string invokeActivityID, Guid instanceId, IDictionary<string, object> namedArguments, WorkflowInstance workflowInstance) { this.rootActivity = rootActivity; this.InstanceId = instanceId; // Set the persisted State properties this.rootActivity.SetValue(WorkflowExecutor.ContextIdProperty, 0); this.rootActivity.SetValue(WorkflowInstanceIdProperty, instanceId); this.WorkflowStatus = WorkflowStatus.Created; this.rootActivity.SetValue(Activity.ActivityExecutionContextInfoProperty, new ActivityExecutionContextInfo(this.rootActivity.QualifiedName, GetNewContextId(), instanceId, -1)); this.rootActivity.SetValue(Activity.ActivityContextGuidProperty, instanceId); this.rootActivity.SetValue(WorkflowExecutor.IsIdleProperty, true); this.isInstanceIdle = true; // set workflow executor this.rootActivity.SetValue(WorkflowExecutor.WorkflowExecutorProperty, this); // initialize the root activity RefreshWorkflowDefinition(); Activity workflowDefinition = this.WorkflowDefinition; if (workflowDefinition == null) throw new InvalidOperationException("workflowDefinition"); ((IDependencyObjectAccessor)this.rootActivity).InitializeActivatingInstanceForRuntime(null, this); this.rootActivity.FixUpMetaProperties(workflowDefinition); _runtime = workflowInstance.WorkflowRuntime; if (invokerExec != null) { List<string> calleeBase = new List<string>(); TrackingCallingState parentTCS = (TrackingCallingState)invokerExec.rootActivity.GetValue(WorkflowExecutor.TrackingCallingStateProperty); if ((parentTCS != null) && (parentTCS.CallerActivityPathProxy != null)) { foreach (string qualifiedID in parentTCS.CallerActivityPathProxy) calleeBase.Add(qualifiedID); } calleeBase.Add(invokeActivityID); // // This has been exec'd by another instance // Set up tracking info to allow linking instances Debug.Assert(invokeActivityID != null && invokeActivityID.Length > 0); TrackingCallingState trackingCallingState = new TrackingCallingState(); trackingCallingState.CallerActivityPathProxy = calleeBase; trackingCallingState.CallerWorkflowInstanceId = invokerExec.InstanceId; trackingCallingState.CallerContextGuid = ((ActivityExecutionContextInfo)ContextActivityUtils.ContextActivity(invokerExec.CurrentActivity).GetValue(Activity.ActivityExecutionContextInfoProperty)).ContextGuid; if (null == invokerExec.CurrentActivity.Parent) trackingCallingState.CallerParentContextGuid = trackingCallingState.CallerContextGuid; else trackingCallingState.CallerParentContextGuid = ((ActivityExecutionContextInfo)ContextActivityUtils.ContextActivity(invokerExec.CurrentActivity.Parent).GetValue(Activity.ActivityExecutionContextInfoProperty)).ContextGuid; this.rootActivity.SetValue(WorkflowExecutor.TrackingCallingStateProperty, trackingCallingState); } _setInArgsOnCompanion(namedArguments); this.schedulingContext = new Scheduler(this, true); this._schedulerLock = LockFactory.CreateWorkflowSchedulerLock(this.InstanceId); qService = new WorkflowQueuingService(this); _workflowInstance = workflowInstance; TimerQueue = new TimerEventSubscriptionCollection(this, this.InstanceId); // register the dynamic activity using (new ServiceEnvironment(this.rootActivity)) { using (SetCurrentActivity(this.rootActivity)) { this.RegisterDynamicActivity(this.rootActivity, false); } } }
internal WorkflowQueue(WorkflowQueuingService qService, IComparable queueName) { this.qService = qService; this.queueName = queueName; }
private void ReloadHelper(Activity rootActivity) { this.rootActivity = rootActivity; this.InstanceId = (Guid) rootActivity.GetValue(WorkflowInstanceIdProperty); this.rootActivity.SetValue(WorkflowExecutorProperty, this); this._schedulerLock = LockFactory.CreateWorkflowSchedulerLock(this.InstanceId); this.schedulingContext = new System.Workflow.Runtime.Scheduler(this, false); this.qService = new WorkflowQueuingService(this); WorkflowTrace.Runtime.TraceEvent(TraceEventType.Information, 0, "Workflow Runtime: WorkflowExecutor: Loading instance {0}", new object[] { this.InstanceIdString }); using (new ServiceEnvironment(this.rootActivity)) { switch (this.WorkflowStatus) { case System.Workflow.Runtime.WorkflowStatus.Completed: case System.Workflow.Runtime.WorkflowStatus.Terminated: WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, "Workflow Runtime: WorkflowExecutor: attempt to load a completed/terminated instance: {0}", new object[] { this.InstanceIdString }); throw new InvalidOperationException(ExecutionStringManager.InvalidAttemptToLoad); } this._resourceManager = new VolatileResourceManager(); this._runtime = this._workflowInstance.WorkflowRuntime; Queue<Activity> queue = new Queue<Activity>(); queue.Enqueue(this.rootActivity); while (queue.Count > 0) { Activity dynamicActivity = queue.Dequeue(); ((IDependencyObjectAccessor) dynamicActivity).InitializeInstanceForRuntime(this); this.RegisterDynamicActivity(dynamicActivity, true); IList<Activity> list = (IList<Activity>) dynamicActivity.GetValue(Activity.ActiveExecutionContextsProperty); if (list != null) { foreach (Activity activity2 in list) { queue.Enqueue(activity2); } } } } this.isInstanceIdle = (bool) this.rootActivity.GetValue(IsIdleProperty); this.RefreshWorkflowDefinition(); }
internal void Initialize(Activity rootActivity, WorkflowExecutor invokerExec, string invokeActivityID, Guid instanceId, IDictionary<string, object> namedArguments, System.Workflow.Runtime.WorkflowInstance workflowInstance) { this.rootActivity = rootActivity; this.InstanceId = instanceId; this.rootActivity.SetValue(ContextIdProperty, 0); this.rootActivity.SetValue(WorkflowInstanceIdProperty, instanceId); this.WorkflowStatus = System.Workflow.Runtime.WorkflowStatus.Created; this.rootActivity.SetValue(Activity.ActivityExecutionContextInfoProperty, new ActivityExecutionContextInfo(this.rootActivity.QualifiedName, this.GetNewContextId(), instanceId, -1)); this.rootActivity.SetValue(Activity.ActivityContextGuidProperty, instanceId); this.rootActivity.SetValue(IsIdleProperty, true); this.isInstanceIdle = true; this.rootActivity.SetValue(WorkflowExecutorProperty, this); this.RefreshWorkflowDefinition(); Activity workflowDefinition = this.WorkflowDefinition; if (workflowDefinition == null) { throw new InvalidOperationException("workflowDefinition"); } ((IDependencyObjectAccessor) this.rootActivity).InitializeActivatingInstanceForRuntime(null, this); this.rootActivity.FixUpMetaProperties(workflowDefinition); this._runtime = workflowInstance.WorkflowRuntime; if (invokerExec != null) { List<string> list = new List<string>(); System.Workflow.Runtime.TrackingCallingState state = (System.Workflow.Runtime.TrackingCallingState) invokerExec.rootActivity.GetValue(TrackingCallingStateProperty); if ((state != null) && (state.CallerActivityPathProxy != null)) { foreach (string str in state.CallerActivityPathProxy) { list.Add(str); } } list.Add(invokeActivityID); System.Workflow.Runtime.TrackingCallingState state2 = new System.Workflow.Runtime.TrackingCallingState { CallerActivityPathProxy = list, CallerWorkflowInstanceId = invokerExec.InstanceId, CallerContextGuid = ((ActivityExecutionContextInfo) ContextActivityUtils.ContextActivity(invokerExec.CurrentActivity).GetValue(Activity.ActivityExecutionContextInfoProperty)).ContextGuid }; if (invokerExec.CurrentActivity.Parent == null) { state2.CallerParentContextGuid = state2.CallerContextGuid; } else { state2.CallerParentContextGuid = ((ActivityExecutionContextInfo) ContextActivityUtils.ContextActivity(invokerExec.CurrentActivity.Parent).GetValue(Activity.ActivityExecutionContextInfoProperty)).ContextGuid; } this.rootActivity.SetValue(TrackingCallingStateProperty, state2); } this._setInArgsOnCompanion(namedArguments); this.schedulingContext = new System.Workflow.Runtime.Scheduler(this, true); this._schedulerLock = LockFactory.CreateWorkflowSchedulerLock(this.InstanceId); this.qService = new WorkflowQueuingService(this); this._workflowInstance = workflowInstance; this.TimerQueue = new TimerEventSubscriptionCollection(this, this.InstanceId); using (new ServiceEnvironment(this.rootActivity)) { using (this.SetCurrentActivity(this.rootActivity)) { this.RegisterDynamicActivity(this.rootActivity, false); } } }
protected override void OnActivityExecutionContextLoad(IServiceProvider provider) { Logger.Instance.WriteMethodEntry(EventIdentifier.AsyncCreateResourceOnActivityExecutionContextLoad); try { // Ideally we would set CallContext in OnActivityExecutionContextLoad instead here in Execute // as OnActivityExecutionContextLoad gets called on each hydration and rehydration of the workflow instance // but looks like it's invoked on a different thread context than the rest of the workflow instance execution. // To minimize the loss of the CallContext on rehydration, we'll set it in the Execute of every WAL child activities. // It will still get lost (momentarily) when the workflow is persisted in the middle of the execution of a replicator activity, for example. Logger.SetContextItem(this, this.WorkflowInstanceId); base.OnActivityExecutionContextLoad(provider); // Load the data access service via reflection Assembly assembly = Assembly.GetAssembly(typeof(UpdateResourceActivity)); const string TypeName = "Microsoft.ResourceManagement.Workflow.Runtime.DataAccessService"; this.dataAccessServiceType = assembly.GetType(TypeName); if (this.dataAccessServiceType == null) { throw Logger.Instance.ReportError(new WorkflowActivityLibraryException(Messages.DataAccessService_TypeLoadingFailedError, TypeName)); } this.dataAccessService = provider.GetService(this.dataAccessServiceType); this.queuingService = (WorkflowQueuingService)provider.GetService(typeof(WorkflowQueuingService)); } finally { Logger.Instance.WriteMethodExit(EventIdentifier.AsyncCreateResourceOnActivityExecutionContextLoad); } }
private void RemoveMessageArrivedEventHandler(WorkflowQueuingService handler) { lock (this.SyncRoot) { if (this.messageArrivalEventHandlers != null) { this.messageArrivalEventHandlers.Remove(handler); } if (this.dirtyQueues != null) { foreach (IComparable comparable in this.dirtyQueues) { this.GetQueue(comparable).Dirty = false; } } } }
/// <summary> /// Creates the workflow program queue. /// </summary> /// <param name="workflowQueuingService">The workflow queuing service.</param> /// <param name="activity">The activity to be used for deriving the queue name.</param> /// <returns>The <see cref="WorkflowQueue"/> object.</returns> private static WorkflowQueue CreateWorkflowProgramQueue(WorkflowQueuingService workflowQueuingService, Activity activity) { Logger.Instance.WriteMethodEntry(EventIdentifier.AsyncUpdateResourceCreateWorkflowProgramQueue); try { string queueName = string.Format(CultureInfo.InvariantCulture, "{0}/{1}", activity.QualifiedName, Guid.NewGuid()); Logger.Instance.WriteVerbose(EventIdentifier.AsyncUpdateResourceCreateWorkflowProgramQueue, "AsynchronousUpdateResource workflow queue name is: '{0}'.", queueName); return workflowQueuingService.CreateWorkflowQueue(queueName, false); } finally { Logger.Instance.WriteMethodExit(EventIdentifier.AsyncUpdateResourceCreateWorkflowProgramQueue); } }
private void RemoveMessageArrivedEventHandler(WorkflowQueuingService handler) { lock (SyncRoot) { if (this.messageArrivalEventHandlers != null) this.messageArrivalEventHandlers.Remove(handler); if (this.dirtyQueues != null) { foreach (IComparable queueName in this.dirtyQueues) { EventQueueState qState = GetQueue(queueName); qState.Dirty = false; } } } }
/// <summary> /// Deletes the workflow program queue. /// </summary> /// <param name="workflowQueuingService">The workflow queuing service.</param> /// <param name="queue">The queue name.</param> private static void DeleteWorkflowProgramQueue(WorkflowQueuingService workflowQueuingService, WorkflowQueue queue) { Logger.Instance.WriteMethodEntry(EventIdentifier.AsyncUpdateResourceDeleteWorkflowProgramQueue); try { if (workflowQueuingService.Exists(queue.QueueName)) { workflowQueuingService.DeleteWorkflowQueue(queue.QueueName); Logger.Instance.WriteVerbose(EventIdentifier.AsyncUpdateResourceDeleteWorkflowProgramQueue, "AsynchronousUpdateResource deleted workflow queue: '{0}'.", queue.QueueName); } } finally { Logger.Instance.WriteMethodExit(EventIdentifier.AsyncUpdateResourceDeleteWorkflowProgramQueue); } }
void PrivateInitialize(Activity rootActivity, Guid instanceId, IList<PropertyInfo> outputProperties, Activity workflowDefinition) { this.instanceId = instanceId; this.rootActivity = rootActivity; this.contextActivityMap = new Dictionary<int, Activity>(); this.scheduler = new Scheduler(this); this.workflowQueuingService = new WorkflowQueuingService(this); this.outputProperties = outputProperties; this.resourceManager = new VolatileResourceManager(); this.rootActivity.SetValue(System.Workflow.ComponentModel.Activity.WorkflowDefinitionProperty, workflowDefinition); this.rootActivity.SetValue(WorkflowExecutor.WorkflowExecutorProperty, this); }