/// <summary> /// PSActivityHostArguments /// </summary> /// <param name="streams"></param> internal PSResumableActivityContext(PowerShellStreams <PSObject, PSObject> streams) { Streams = streams; Error = null; Failed = false; SupportDisconnectedStreams = true; }
internal PSResumableActivityContext(PowerShellStreams<PSObject, PSObject> streams) { this.Streams = streams; this.Error = null; this.Failed = false; this.SupportDisconnectedStreams = true; }
public virtual void StartResumablePSCommand(Guid jobInstanceId, Bookmark bookmark, System.Management.Automation.PowerShell command, PowerShellStreams <PSObject, PSObject> streams, PSActivityEnvironment environment, PSActivity activityInstance) { throw new NotImplementedException(); }
// This function executes the activity. // It is highly recommended to not to block the execution of this function while executing the activity. // All the information should be logged into the queue and the function should be returned. // In a separate thread or on a separate machine, read the data from the queue and execute the activity. // Once the activity action is completed the bookmark should be resumed. // Design the activity controller to hanlde multiple activities from one workflowflow. public override void StartResumablePSCommand(Guid jobInstanceId, Bookmark bookmark, PowerShell command, PowerShellStreams<PSObject, PSObject> streams, PSActivityEnvironment environment, PSActivity activityInstance) { ActivityActionData data = new ActivityActionData(); data.jobInstanceId = jobInstanceId; data.bookmark = bookmark; data.command = command; data.streams = streams; data.environment = environment; // Add the request to the queue. ActivityActionsQueue.TryAdd(jobInstanceId, data); // Return the fucntion and allow the workfow do other work in parallel. // There should be a servicing thead which gets the data from the queue and perform the action. // To keep this sample simple, the worker thread calls the servicing function. ThreadPool.QueueUserWorkItem(ServiceRequests, jobInstanceId); }
/// <summary> /// Dispose the streams to save memory /// </summary> public override void DisposeStreams() { if (_streams == null) return; lock (SyncLock) { if (_streams == null) return; _streamsDisposed = true; UnregisterHandlersForDataAdding(_streams); _streams.Dispose(); _streams = null; } }
/// <summary> /// Workflow instance constructor for shutdown or crashed workflows. /// </summary> /// <param name="runtime"></param> /// <param name="instanceId"></param> internal PSWorkflowApplicationInstance(PSWorkflowRuntime runtime, PSWorkflowId instanceId) { Tracer.WriteMessage("Creating Workflow instance after crash and shutdown workflow."); InitializePSWorkflowApplicationInstance(runtime); this._definition = null; this._metadatas = null; this._streams = null; this._timers = null; this.id = instanceId.Guid; this.creationMode = WorkflowInstanceCreationMode.AfterCrashOrShutdown; _stores = Runtime.Configuration.CreatePSWorkflowInstanceStore(this); this._remoteActivityState = null; }
private void UnregisterHandlersForDataAdding(PowerShellStreams<PSObject, PSObject> streams) { if (streams.OutputStream != null) streams.OutputStream.DataAdding -= HandleOutputDataAdding; if (streams.ErrorStream != null) streams.ErrorStream.DataAdding -= HandleErrorDataAdding; if (streams.DebugStream != null) streams.DebugStream.DataAdding -= HandleInformationalDataAdding; if (streams.VerboseStream != null) streams.VerboseStream.DataAdding -= HandleInformationalDataAdding; if (streams.WarningStream != null) streams.WarningStream.DataAdding -= HandleInformationalDataAdding; if (streams.ProgressStream != null) streams.ProgressStream.DataAdding -= HandleProgressDataAdding; if (streams.InformationStream != null) streams.InformationStream.DataAdding -= HandleInformationDataAdding; }
public virtual void StartResumablePSCommand(Guid jobInstanceId, Bookmark bookmark, System.Management.Automation.PowerShell command, PowerShellStreams<PSObject, PSObject> streams, PSActivityEnvironment environment, PSActivity activityInstance) { throw new NotImplementedException(); }
private PowerShellStreams<PSObject, PSObject> DeserializeWorkflowStreamsFromStore() { PowerShellStreams<PSObject, PSObject> powerShellStream = new PowerShellStreams<PSObject, PSObject>(null); Guid id = base.PSWorkflowInstance.Id; string str = Path.Combine(this._configuration.InstanceStorePath, id.ToString(), this.Streams); if (Directory.Exists(str)) { if (!this._disablePersistenceLimits) { powerShellStream.InputStream = (PSDataCollection<PSObject>)this.DeserializeObject(this.Decrypt(this.LoadFromFile(Path.Combine(str, this.InputStream_xml)))); powerShellStream.OutputStream = (PSDataCollection<PSObject>)this.DeserializeObject(this.Decrypt(this.LoadFromFile(Path.Combine(str, this.OutputStream_xml)))); powerShellStream.ErrorStream = (PSDataCollection<ErrorRecord>)this.DeserializeObject(this.Decrypt(this.LoadFromFile(Path.Combine(str, this.ErrorStream_xml)))); powerShellStream.WarningStream = (PSDataCollection<WarningRecord>)this.DeserializeObject(this.Decrypt(this.LoadFromFile(Path.Combine(str, this.WarningStream_xml)))); powerShellStream.VerboseStream = (PSDataCollection<VerboseRecord>)this.DeserializeObject(this.Decrypt(this.LoadFromFile(Path.Combine(str, this.VerboseStream_xml)))); powerShellStream.ProgressStream = (PSDataCollection<ProgressRecord>)this.DeserializeObject(this.Decrypt(this.LoadFromFile(Path.Combine(str, this.ProgressStream_xml)))); powerShellStream.DebugStream = (PSDataCollection<DebugRecord>)this.DeserializeObject(this.Decrypt(this.LoadFromFile(Path.Combine(str, this.DebugStream_xml)))); } else { powerShellStream.InputStream = (PSDataCollection<PSObject>)this.LoadFromFileAndDeserialize(Path.Combine(str, this.InputStream_xml)); powerShellStream.OutputStream = (PSDataCollection<PSObject>)this.LoadFromFileAndDeserialize(Path.Combine(str, this.OutputStream_xml)); powerShellStream.ErrorStream = (PSDataCollection<ErrorRecord>)this.LoadFromFileAndDeserialize(Path.Combine(str, this.ErrorStream_xml)); powerShellStream.WarningStream = (PSDataCollection<WarningRecord>)this.LoadFromFileAndDeserialize(Path.Combine(str, this.WarningStream_xml)); powerShellStream.VerboseStream = (PSDataCollection<VerboseRecord>)this.LoadFromFileAndDeserialize(Path.Combine(str, this.VerboseStream_xml)); powerShellStream.ProgressStream = (PSDataCollection<ProgressRecord>)this.LoadFromFileAndDeserialize(Path.Combine(str, this.ProgressStream_xml)); powerShellStream.DebugStream = (PSDataCollection<DebugRecord>)this.LoadFromFileAndDeserialize(Path.Combine(str, this.DebugStream_xml)); } } return powerShellStream; }
private static void BeginExecuteOneCommand(RunCommandsArguments args) { PSActivityContext pSActivityContext = args.PSActivityContext; PSWorkflowHost workflowHost = args.WorkflowHost; ActivityImplementationContext implementationContext = args.ImplementationContext; PSDataCollection<PSObject> input = args.Input; PSDataCollection<PSObject> output = args.Output; int commandExecutionType = args.CommandExecutionType; PowerShellTraceSource traceSource = PowerShellTraceSourceFactory.GetTraceSource(); using (traceSource) { PowerShell powerShellInstance = implementationContext.PowerShellInstance; object[] objArray = new object[1]; objArray[0] = powerShellInstance; traceSource.WriteMessage(string.Format(CultureInfo.InvariantCulture, "BEGIN BeginExecuteOneCommand {0}.", objArray)); int num = commandExecutionType; switch (num) { case 0: { powerShellInstance.Runspace.ThreadOptions = PSThreadOptions.UseCurrentThread; ThreadPool.QueueUserWorkItem(new WaitCallback(PSActivity.InitializeRunspaceAndExecuteCommandWorker), args); break; } case 1: { ThreadPool.QueueUserWorkItem(new WaitCallback(PSActivity.ExecuteOneRunspaceFreeCommandWorker), args); break; } case 2: { if (!PSActivity.CheckForCancel(pSActivityContext)) { PSResumableActivityHostController pSActivityHostController = workflowHost.PSActivityHostController as PSResumableActivityHostController; if (pSActivityHostController == null) { PSOutOfProcessActivityController pSOutOfProcessActivityController = workflowHost.PSActivityHostController as PSOutOfProcessActivityController; if (pSOutOfProcessActivityController == null) { break; } PSActivity.AddHandlersToStreams(powerShellInstance, args); IAsyncResult asyncResult = pSOutOfProcessActivityController.BeginInvokePowerShell(powerShellInstance, input, output, implementationContext.PSActivityEnvironment, new AsyncCallback(PSActivity.ActivityHostManagerCallback), args); pSActivityContext.AsyncResults.Enqueue(asyncResult); break; } else { PowerShellStreams<PSObject, PSObject> powerShellStream = new PowerShellStreams<PSObject, PSObject>(); if (!pSActivityHostController.SupportDisconnectedPSStreams) { powerShellStream.InputStream = input; powerShellStream.OutputStream = output; powerShellStream.DebugStream = powerShellInstance.Streams.Debug; powerShellStream.ErrorStream = powerShellInstance.Streams.Error; powerShellStream.ProgressStream = powerShellInstance.Streams.Progress; powerShellStream.VerboseStream = powerShellInstance.Streams.Verbose; powerShellStream.WarningStream = powerShellInstance.Streams.Warning; } else { powerShellStream.InputStream = input; powerShellStream.OutputStream = new PSDataCollection<PSObject>(); powerShellStream.ErrorStream = new PSDataCollection<ErrorRecord>(); powerShellStream.DebugStream = new PSDataCollection<DebugRecord>(); powerShellStream.ProgressStream = new PSDataCollection<ProgressRecord>(); powerShellStream.VerboseStream = new PSDataCollection<VerboseRecord>(); powerShellStream.WarningStream = new PSDataCollection<WarningRecord>(); } pSActivityHostController.StartResumablePSCommand(args.PSActivityContext.JobInstanceId, (Bookmark)args.PSActivityContext.AsyncState, powerShellInstance, powerShellStream, implementationContext.PSActivityEnvironment, (PSActivity)pSActivityContext.ActivityObject); break; } } else { return; } } case 3: { PSActivity.ArgsTableForRunspaces.TryAdd(powerShellInstance.Runspace.InstanceId, args); PSActivity.InitializeRunspaceAndExecuteCommandWorker(args); break; } case 4: { ThreadPool.QueueUserWorkItem(new WaitCallback(PSActivity.InitializeRunspaceAndExecuteCommandWorker), args); break; } case 5: { PSActivity.ExecuteCleanupActivity(args); break; } } traceSource.WriteMessage("END BeginExecuteOneCommand"); } }
/// <summary> /// ResumeBookmark /// </summary> /// <param name="bookmark"></param> /// <param name="supportDisconnectedStreams"></param> /// <param name="streams"></param> /// <param name="exception"></param> public void ResumeBookmark(Bookmark bookmark, bool supportDisconnectedStreams, PowerShellStreams<PSObject, PSObject> streams, Exception exception) { if (bookmark == null) throw new ArgumentNullException("bookmark"); if (streams == null) throw new ArgumentNullException("streams"); if (exception == null) throw new ArgumentNullException("exception"); PSResumableActivityContext arguments = new PSResumableActivityContext(streams); arguments.SupportDisconnectedStreams = supportDisconnectedStreams; arguments.Failed = true; arguments.Error = exception; DoResumeBookmark(bookmark, arguments); }
public override void DisposeStreams() { if (this._streams != null) { lock (base.SyncLock) { if (this._streams != null) { this._streamsDisposed = true; this.UnregisterHandlersForDataAdding(this._streams); this._streams.Dispose(); this._streams = null; } } return; } else { return; } }
internal PSWorkflowApplicationInstance(PSWorkflowRuntime runtime, PSWorkflowId instanceId) { this.Tracer = PowerShellTraceSourceFactory.GetTraceSource(); this.wfAppNeverLoaded = true; this.ReactivateSync = new object(); if (runtime != null) { this.Tracer.WriteMessage("Creating Workflow instance after crash and shutdown workflow."); this._definition = null; this._metadatas = null; this._streams = null; this._timers = null; this.id = instanceId.Guid; this.creationMode = WorkflowInstanceCreationMode.AfterCrashOrShutdown; this.PersistAfterNextPSActivity = false; this.suspendAtNextCheckpoint = false; base.Runtime = runtime; this._stores = base.Runtime.Configuration.CreatePSWorkflowInstanceStore(this); this.asyncExecutionCollection = new Dictionary<string, PSActivityContext>(); base.ForceDisableStartOrEndPersistence = false; return; } else { throw new ArgumentNullException("runtime"); } }
internal PSWorkflowApplicationInstance(PSWorkflowRuntime runtime, PSWorkflowDefinition definition, PSWorkflowContext metadata, PSDataCollection<PSObject> pipelineInput, PSWorkflowJob job) { this.Tracer = PowerShellTraceSourceFactory.GetTraceSource(); this.wfAppNeverLoaded = true; this.ReactivateSync = new object(); if (runtime != null) { this.Tracer.WriteMessage("Creating Workflow instance."); this._definition = definition; this._metadatas = metadata; this._streams = new PowerShellStreams<PSObject, PSObject>(pipelineInput); this.RegisterHandlersForDataAdding(this._streams); this._timers = new PSWorkflowTimer(this); this.creationMode = WorkflowInstanceCreationMode.Normal; this.PersistAfterNextPSActivity = false; this.suspendAtNextCheckpoint = false; this._job = job; base.Runtime = runtime; this._stores = base.Runtime.Configuration.CreatePSWorkflowInstanceStore(this); this.asyncExecutionCollection = new Dictionary<string, PSActivityContext>(); base.ForceDisableStartOrEndPersistence = false; return; } else { throw new ArgumentNullException("runtime"); } }
private void UnregisterHandlersForDataAdding(PowerShellStreams<PSObject, PSObject> streams) { if (streams.OutputStream != null) { streams.OutputStream.DataAdding -= new EventHandler<DataAddingEventArgs>(this.HandleOutputDataAdding); } if (streams.ErrorStream != null) { streams.ErrorStream.DataAdding -= new EventHandler<DataAddingEventArgs>(this.HandleErrorDataAdding); } if (streams.DebugStream != null) { streams.DebugStream.DataAdding -= new EventHandler<DataAddingEventArgs>(this.HandleInformationalDataAdding); } if (streams.VerboseStream != null) { streams.VerboseStream.DataAdding -= new EventHandler<DataAddingEventArgs>(this.HandleInformationalDataAdding); } if (streams.WarningStream != null) { streams.WarningStream.DataAdding -= new EventHandler<DataAddingEventArgs>(this.HandleInformationalDataAdding); } if (streams.ProgressStream != null) { streams.ProgressStream.DataAdding -= new EventHandler<DataAddingEventArgs>(this.HandleProgressDataAdding); } }
/// <summary> /// Workflow instance constructor. /// </summary> /// <param name="runtime"></param> /// <param name="definition">The workflow definition.</param> /// <param name="metadata">The metadata which includes parameters etc.</param> /// <param name="pipelineInput">This is input coming from pipeline, which is added to the input stream.</param> /// <param name="job"></param> internal PSWorkflowApplicationInstance( PSWorkflowRuntime runtime, PSWorkflowDefinition definition, PSWorkflowContext metadata, PSDataCollection<PSObject> pipelineInput, PSWorkflowJob job) { Tracer.WriteMessage("Creating Workflow instance."); InitializePSWorkflowApplicationInstance(runtime); this._definition = definition; this._metadatas = metadata; this._streams = new PowerShellStreams<PSObject, PSObject>(pipelineInput); RegisterHandlersForDataAdding(_streams); this._timers = new PSWorkflowTimer(this); this.creationMode = WorkflowInstanceCreationMode.Normal; _job = job; _stores = Runtime.Configuration.CreatePSWorkflowInstanceStore(this); this._remoteActivityState = new PSWorkflowRemoteActivityState(_stores); }
// This function executes the activity. // It is highly recommended to not to block the execution of this function while executing the activity. // All the information should be logged into the queue and the function should be returned. // In a separate thread or on a separate machine, read the data from the queue and execute the activity. // Once the activity action is completed the bookmark should be resumed. // Design the activity controller to hanlde multiple activities from one workflowflow. public override void StartResumablePSCommand(Guid jobInstanceId, Bookmark bookmark, PowerShell command, PowerShellStreams <PSObject, PSObject> streams, PSActivityEnvironment environment, PSActivity activityInstance) { ActivityActionData data = new ActivityActionData(); data.jobInstanceId = jobInstanceId; data.bookmark = bookmark; data.command = command; data.streams = streams; data.environment = environment; // Add the request to the queue. ActivityActionsQueue.TryAdd(jobInstanceId, data); // Return the fucntion and allow the workfow do other work in parallel. // There should be a servicing thead which gets the data from the queue and perform the action. // To keep this sample simple, the worker thread calls the servicing function. ThreadPool.QueueUserWorkItem(ServiceRequests, jobInstanceId); }
public void ResumeBookmark(Bookmark bookmark, bool supportDisconnectedStreams, PowerShellStreams<PSObject, PSObject> streams, Exception exception) { if (bookmark != null) { if (streams != null) { if (exception != null) { PSResumableActivityContext pSResumableActivityContext = new PSResumableActivityContext(streams); pSResumableActivityContext.SupportDisconnectedStreams = supportDisconnectedStreams; pSResumableActivityContext.Failed = true; pSResumableActivityContext.Error = exception; this.DoResumeBookmark(bookmark, pSResumableActivityContext); return; } else { throw new ArgumentNullException("exception"); } } else { throw new ArgumentNullException("streams"); } } else { throw new ArgumentNullException("bookmark"); } }