/// <summary> /// Add any services needed by the runtime engine /// </summary> /// <param name="instance"></param> private void AddServices(WorkflowRuntime instance) { #if CUSTOM_PERSISTENCE //use the custom file based persistence service _persistence = new FileWorkflowPersistenceService(); instance.AddService(_persistence); #else //use the standard SQL Server persistence service String connStringPersistence = String.Format( "Initial Catalog={0};Data Source={1};Integrated Security={2};", "WorkflowPersistence", @"localhost\SQLEXPRESS", "SSPI"); _persistence = new SqlWorkflowPersistenceService(connStringPersistence, true, new TimeSpan(0, 2, 0), new TimeSpan(0, 0, 5)); instance.AddService(_persistence); #endif //add the external data exchange service to the runtime ExternalDataExchangeService exchangeService = new ExternalDataExchangeService(); instance.AddService(exchangeService); //add our local service _persistenceDemoService = new PersistenceDemoService(); exchangeService.AddService(_persistenceDemoService); }
// 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))); } }
// Methods public void AddService(object service_toadd) { WorkflowRuntimeService runtime_service = service_toadd as WorkflowRuntimeService; WorkflowPersistenceService persistence_service = service_toadd as WorkflowPersistenceService; if (service_toadd == null) { throw new ArgumentNullException("service is a null reference "); } foreach (object service in services) { if (service == service_toadd) { throw new InvalidOperationException("Cannot add a service that already exists."); } if ((persistence_service != null) && (service is WorkflowPersistenceService)) { throw new InvalidOperationException("There can be only one persistence service."); } } if (runtime_service != null) { runtime_service.SetRuntime(this); } services.Add(service_toadd); }
// Load the completed activity state. protected override Activity LoadCompletedContextActivity(Guid activityId, Activity outerActivity) { Console.WriteLine("Loading completed activity context: {0}", activityId); byte[] workflowBytes = DeserializeFromFile(activityId); Activity deserializedActivities = WorkflowPersistenceService.RestoreFromDefaultSerializedForm(workflowBytes, outerActivity); return(deserializedActivities); }
// Save the completed activity state. protected override void SaveCompletedContextActivity(Activity activity) { Guid contextGuid = (Guid)activity.GetValue(Activity.ActivityContextGuidProperty); Console.WriteLine("Saving completed activity context: {0}", contextGuid); SerializeToFile( WorkflowPersistenceService.GetDefaultSerializedForm(activity), contextGuid); }
public SkipUnloadOnFirstIdleWorkflowPersistenceService(WorkflowPersistenceService inner) { if (inner == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("inner"); } this.inner = inner; }
protected override void SaveWorkflowInstanceState(Activity rootActivity, bool unlock) { WorkflowStatus workflowStatus = WorkflowPersistenceService.GetWorkflowStatus(rootActivity); if (workflowStatus == WorkflowStatus.Terminated) { string workflowError = WorkflowPersistenceService.GetSuspendOrTerminateInfo(rootActivity); //Logger.Log.Error(workflowError); return; } base.SaveWorkflowInstanceState(rootActivity, unlock); }
/// <summary> /// Persist the current state of the entire workflow /// </summary> /// <param name="rootActivity"></param> /// <param name="unlock"></param> protected override void SaveWorkflowInstanceState( Activity rootActivity, bool unlock) { //get the workflow instance Id Guid instanceId = WorkflowEnvironment.WorkflowInstanceId; //determine the status of the workflow WorkflowStatus status = WorkflowPersistenceService.GetWorkflowStatus(rootActivity); switch (status) { case WorkflowStatus.Completed: case WorkflowStatus.Terminated: //delete the persisted workflow DeleteWorkflow(instanceId); break; default: //save the workflow Serialize(instanceId, Guid.Empty, rootActivity); break; } }
// Load workflow instance state. protected override Activity LoadWorkflowInstanceState(Guid instanceId) { Console.WriteLine("Loading instance: {0}\n", instanceId); byte[] workflowBytes = DeserializeFromFile(instanceId); return(WorkflowPersistenceService.RestoreFromDefaultSerializedForm(workflowBytes, null)); }
public void ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase) { if (description == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("description"); } if (serviceHostBase == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("serviceHostBase"); } if (description.Behaviors == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("description", SR2.GetString(SR2.NoBehaviors)); } if (description.Endpoints == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("description", SR2.GetString(SR2.NoEndpoints)); } bool syncContextRegistered = false; WorkflowRuntimeBehavior workflowRuntimeBehavior = description.Behaviors.Find <WorkflowRuntimeBehavior>(); if (workflowRuntimeBehavior == null) { workflowRuntimeBehavior = new WorkflowRuntimeBehavior(); description.Behaviors.Add(workflowRuntimeBehavior); } WorkflowPersistenceService persistenceService = workflowRuntimeBehavior.WorkflowRuntime.GetService <WorkflowPersistenceService>(); if (persistenceService != null) { bool wasRuntimeStarted = workflowRuntimeBehavior.WorkflowRuntime.IsStarted; if (wasRuntimeStarted) { workflowRuntimeBehavior.WorkflowRuntime.StopRuntime(); } workflowRuntimeBehavior.WorkflowRuntime.RemoveService(persistenceService); workflowRuntimeBehavior.WorkflowRuntime.AddService(new SkipUnloadOnFirstIdleWorkflowPersistenceService(persistenceService)); if (wasRuntimeStarted) { workflowRuntimeBehavior.WorkflowRuntime.StartRuntime(); } } this.workflowDefinitionContext.Register(workflowRuntimeBehavior.WorkflowRuntime, workflowRuntimeBehavior.ValidateOnCreate); WorkflowInstanceContextProvider instanceContextProvider = new WorkflowInstanceContextProvider( serviceHostBase, false, this.workflowDefinitionContext ); WorkflowInstanceContextProvider singleCallInstanceContextProvider = null; IInstanceProvider instanceProvider = new WorkflowInstanceProvider(instanceContextProvider); ServiceDebugBehavior serviceDebugBehavior = description.Behaviors.Find <ServiceDebugBehavior>(); bool includeExceptionDetailsInFaults = this.IncludeExceptionDetailInFaults; if (serviceDebugBehavior != null) { includeExceptionDetailsInFaults |= serviceDebugBehavior.IncludeExceptionDetailInFaults; } IErrorHandler workflowOperationErrorHandler = new WorkflowOperationErrorHandler(includeExceptionDetailsInFaults); foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers) { ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher; if (channelDispatcher != null && channelDispatcher.HasApplicationEndpoints()) { channelDispatcher.IncludeExceptionDetailInFaults = includeExceptionDetailsInFaults; channelDispatcher.ErrorHandlers.Add(workflowOperationErrorHandler); foreach (EndpointDispatcher endPointDispatcher in channelDispatcher.Endpoints) { if (endPointDispatcher.IsSystemEndpoint) { continue; } ServiceEndpoint serviceEndPoint = description.Endpoints.Find(new XmlQualifiedName(endPointDispatcher.ContractName, endPointDispatcher.ContractNamespace)); if (serviceEndPoint != null) { DispatchRuntime dispatchRuntime = endPointDispatcher.DispatchRuntime; dispatchRuntime.AutomaticInputSessionShutdown = true; dispatchRuntime.ConcurrencyMode = ConcurrencyMode.Single; dispatchRuntime.ValidateMustUnderstand = this.ValidateMustUnderstand; if (!this.UseSynchronizationContext) { dispatchRuntime.SynchronizationContext = null; } else if (!syncContextRegistered) { SynchronizationContextWorkflowSchedulerService syncSchedulerService = workflowRuntimeBehavior.WorkflowRuntime.GetService <SynchronizationContextWorkflowSchedulerService>(); Fx.Assert(syncSchedulerService != null, "Wrong Synchronization Context Set"); syncSchedulerService.SetSynchronizationContext(dispatchRuntime.SynchronizationContext); syncContextRegistered = true; } if (!endPointDispatcher.AddressFilterSetExplicit) { EndpointAddress endPointAddress = endPointDispatcher.OriginalAddress; if ((endPointAddress == null) || (this.AddressFilterMode == AddressFilterMode.Any)) { endPointDispatcher.AddressFilter = new MatchAllMessageFilter(); } else if (this.AddressFilterMode == AddressFilterMode.Prefix) { endPointDispatcher.AddressFilter = new PrefixEndpointAddressMessageFilter(endPointAddress); } else if (this.AddressFilterMode == AddressFilterMode.Exact) { endPointDispatcher.AddressFilter = new EndpointAddressMessageFilter(endPointAddress); } } if (serviceEndPoint.Contract.SessionMode != SessionMode.NotAllowed) { endPointDispatcher.DispatchRuntime.InstanceContextProvider = instanceContextProvider; } else { if (singleCallInstanceContextProvider == null) { singleCallInstanceContextProvider = new WorkflowInstanceContextProvider( serviceHostBase, true, this.workflowDefinitionContext); } endPointDispatcher.DispatchRuntime.InstanceContextProvider = singleCallInstanceContextProvider; } endPointDispatcher.DispatchRuntime.MessageInspectors.Add(new DurableMessageDispatchInspector(serviceEndPoint.Contract.SessionMode)); endPointDispatcher.DispatchRuntime.InstanceProvider = instanceProvider; SetContractFilterToIncludeAllOperations(endPointDispatcher, serviceEndPoint.Contract); } } } } DataContractSerializerServiceBehavior.ApplySerializationSettings(description, this.ignoreExtensionDataObject, this.maxItemsInObjectGraph); }