internal IAsyncResult BeginInvokePowerShell(System.Management.Automation.PowerShell command, PSDataCollection<PSObject> input, PSDataCollection<PSObject> output, PSActivityEnvironment policy, AsyncCallback callback, object state) { if (command != null) { ConnectionAsyncResult connectionAsyncResult = new ConnectionAsyncResult(state, callback, command.InstanceId); this._structuredTracer.OutOfProcessRunspaceStarted(command.ToString()); ActivityInvoker activityInvoker = new ActivityInvoker(); activityInvoker.Input = input; activityInvoker.Output = output; activityInvoker.Policy = policy; activityInvoker.PowerShell = command; activityInvoker.AsyncResult = connectionAsyncResult; ActivityInvoker activityInvoker1 = activityInvoker; connectionAsyncResult.Invoker = activityInvoker1; this._requests.Enqueue(activityInvoker1); PSOutOfProcessActivityController.PerfCountersMgr.UpdateCounterByValue(PSWorkflowPerformanceCounterSetInfo.CounterSetId, 19, (long)1, true); PSOutOfProcessActivityController.PerfCountersMgr.UpdateCounterByValue(PSWorkflowPerformanceCounterSetInfo.CounterSetId, 20, (long)1, true); this.CheckAndStartServicingThread(); return connectionAsyncResult; } else { throw new ArgumentNullException("command"); } }
/// <summary> /// dispose of managed resources /// </summary> /// <param name="disposing">true if being disposed</param> protected void Dispose(bool disposing) { if (!disposing) { return; } if (_isDisposed) { return; } lock (_syncObject) { if (_isDisposed) { return; } _isDisposed = true; } Debug.Assert(_runspace != null, "Runspace is already null"); CloseAndDisposeRunspace(); _processInstance.Dispose(); _currentInvoker = null; _tracer.Dispose(); _perfCountersMgr.UpdateCounterByValue( PSWorkflowPerformanceCounterSetInfo.CounterSetId, PSWorkflowPerformanceCounterIds.ActivityHostMgrDisposedProcessesCount); }
/// <summary> /// Begin invocation of command specified in activity /// </summary> /// <param name="command">pipeline of command to execute</param> /// <param name="input">input collection</param> /// <param name="output">output collection</param> /// <param name="policy">policy to use for the activity</param> /// <param name="callback">optional callback</param> /// <param name="state">optional caller specified state</param> /// <returns>IAsyncResult</returns> internal IAsyncResult BeginInvokePowerShell(System.Management.Automation.PowerShell command, PSDataCollection <PSObject> input, PSDataCollection <PSObject> output, PSActivityEnvironment policy, AsyncCallback callback, object state) { if (command == null) { throw new ArgumentNullException("command"); } ConnectionAsyncResult result = new ConnectionAsyncResult(state, callback, command.InstanceId); _structuredTracer.OutOfProcessRunspaceStarted(command.ToString()); ActivityInvoker invoker = new ActivityInvoker { Input = input, Output = output, Policy = policy, PowerShell = command, AsyncResult = result }; result.Invoker = invoker; _requests.Enqueue(invoker); PerfCountersMgr.UpdateCounterByValue( PSWorkflowPerformanceCounterSetInfo.CounterSetId, PSWorkflowPerformanceCounterIds.ActivityHostMgrIncomingRequestsPerSec); PerfCountersMgr.UpdateCounterByValue( PSWorkflowPerformanceCounterSetInfo.CounterSetId, PSWorkflowPerformanceCounterIds.ActivityHostMgrPendingRequestsQueueLength); CheckAndStartServicingThread(); return(result); }
internal IAsyncResult BeginInvokePowerShell(System.Management.Automation.PowerShell command, PSDataCollection <PSObject> input, PSDataCollection <PSObject> output, PSActivityEnvironment policy, AsyncCallback callback, object state) { if (command != null) { ConnectionAsyncResult connectionAsyncResult = new ConnectionAsyncResult(state, callback, command.InstanceId); this._structuredTracer.OutOfProcessRunspaceStarted(command.ToString()); ActivityInvoker activityInvoker = new ActivityInvoker(); activityInvoker.Input = input; activityInvoker.Output = output; activityInvoker.Policy = policy; activityInvoker.PowerShell = command; activityInvoker.AsyncResult = connectionAsyncResult; ActivityInvoker activityInvoker1 = activityInvoker; connectionAsyncResult.Invoker = activityInvoker1; this._requests.Enqueue(activityInvoker1); PSOutOfProcessActivityController.PerfCountersMgr.UpdateCounterByValue(PSWorkflowPerformanceCounterSetInfo.CounterSetId, 19, (long)1, true); PSOutOfProcessActivityController.PerfCountersMgr.UpdateCounterByValue(PSWorkflowPerformanceCounterSetInfo.CounterSetId, 20, (long)1, true); this.CheckAndStartServicingThread(); return(connectionAsyncResult); } else { throw new ArgumentNullException("command"); } }
protected void Dispose(bool disposing) { if (disposing) { if (!this._isDisposed) { lock (this._syncObject) { if (!this._isDisposed) { this._isDisposed = true; } else { return; } } this.CloseAndDisposeRunspace(); this._processInstance.Dispose(); this._currentInvoker = null; this._tracer.Dispose(); ActivityHostProcess._perfCountersMgr.UpdateCounterByValue(PSWorkflowPerformanceCounterSetInfo.CounterSetId, 22, (long)1, true); return; } else { return; } } else { return; } }
internal void RunPowerShellInActivityHost(System.Management.Automation.PowerShell powershell, PSDataCollection <PSObject> input, PSDataCollection <PSObject> output, PSActivityEnvironment policy, ConnectionAsyncResult asyncResult) { ActivityInvoker activityInvoker = new ActivityInvoker(); activityInvoker.Input = input; activityInvoker.Output = output; activityInvoker.Policy = policy; activityInvoker.PowerShell = powershell; activityInvoker.AsyncResult = asyncResult; ActivityInvoker activityInvoker1 = activityInvoker; this._requests.Enqueue(activityInvoker1); this.CheckAndStartServicingThread(); }
internal void RunPowerShellInActivityHost(System.Management.Automation.PowerShell powershell, PSDataCollection <PSObject> input, PSDataCollection <PSObject> output, PSActivityEnvironment policy, ConnectionAsyncResult asyncResult) { ActivityInvoker invoker = new ActivityInvoker { Input = input, Output = output, Policy = policy, PowerShell = powershell, AsyncResult = asyncResult }; _requests.Enqueue(invoker); CheckAndStartServicingThread(); }
private void RunInProcess(ActivityInvoker invoker, ActivityHostProcess process) { if (!invoker.IsCancelled) { process.Busy = true; Interlocked.Increment(ref this._busyHosts); PSOutOfProcessActivityController.PerfCountersMgr.UpdateCounterByValue(PSWorkflowPerformanceCounterSetInfo.CounterSetId, 16, (long)1, true); Tuple <ActivityHostProcess, ActivityInvoker> tuple = new Tuple <ActivityHostProcess, ActivityInvoker>(process, invoker); ThreadPool.QueueUserWorkItem(new WaitCallback(PSOutOfProcessActivityController.RunPowerShellInActivityHostWorker), tuple); return; } else { return; } }
/// <summary> /// Method called by servicing thread. This method will run the command in the /// specified process on a separate thread /// </summary> /// <param name="invoker"></param> /// <param name="process"></param> private void RunInProcess(ActivityInvoker invoker, ActivityHostProcess process) { if (invoker.IsCancelled) { return; } process.Busy = true; Interlocked.Increment(ref _busyHosts); PerfCountersMgr.UpdateCounterByValue( PSWorkflowPerformanceCounterSetInfo.CounterSetId, PSWorkflowPerformanceCounterIds.ActivityHostMgrBusyProcessesCount); // Adding Tuple object with HostProcess and ActivityInvoker to ThreadPool.QueueUserWorkItem // Back reference on ActivityHostProcess in ActivityInvoker is removed // Tuple <ActivityHostProcess, ActivityInvoker> tupleProcessAndInvoker = new Tuple <ActivityHostProcess, ActivityInvoker>(process, invoker); ThreadPool.QueueUserWorkItem(RunPowerShellInActivityHostWorker, tupleProcessAndInvoker); }
internal void RunPowerShellInActivityHost(System.Management.Automation.PowerShell powershell, PSDataCollection<PSObject> input, PSDataCollection<PSObject> output, PSActivityEnvironment policy, ConnectionAsyncResult asyncResult) { ActivityInvoker invoker = new ActivityInvoker { Input = input, Output = output, Policy = policy, PowerShell = powershell, AsyncResult = asyncResult }; _requests.Enqueue(invoker); CheckAndStartServicingThread(); }
/// <summary> /// dispose of managed resources /// </summary> /// <param name="disposing">true if being disposed</param> protected void Dispose(bool disposing) { if (!disposing) return; if (_isDisposed) return; lock (_syncObject) { if (_isDisposed) return; _isDisposed = true; } Debug.Assert(_runspace != null, "Runspace is already null"); CloseAndDisposeRunspace(); _processInstance.Dispose(); _currentInvoker = null; _tracer.Dispose(); _perfCountersMgr.UpdateCounterByValue( PSWorkflowPerformanceCounterSetInfo.CounterSetId, PSWorkflowPerformanceCounterIds.ActivityHostMgrDisposedProcessesCount); }
internal void PrepareAndRun(ActivityInvoker invoker) { Runspace runspace; bool flag = false; try { try { this._currentInvoker = invoker; for (int i = 1; i <= 10 && !invoker.IsCancelled; i++) { runspace = this.GetRunspace(true); if (runspace.RunspaceStateInfo.State == RunspaceState.Opened) { break; } Thread.Sleep(i * 200); } if (!invoker.IsCancelled) { if (invoker.Policy.Variables.Count > 0) { Guid instanceId = this._runspace.InstanceId; this._tracer.WriteMessage("BEGIN Setting up variables in runspace ", instanceId.ToString()); this.SetVariablesFromPolicy(runspace, invoker.Policy.Variables); Guid guid = this._runspace.InstanceId; this._tracer.WriteMessage("END Setting up variables in runspace ", guid.ToString()); } if (invoker.Policy.Modules.Count > 0) { Guid instanceId1 = this._runspace.InstanceId; this._tracer.WriteMessage("BEGIN Setting up runspace from policy ", instanceId1.ToString()); this.ImportModulesFromPolicy(runspace, invoker.Policy.Modules); Guid guid1 = this._runspace.InstanceId; this._tracer.WriteMessage("END Setting up runspace from policy ", guid1.ToString()); } flag = true; invoker.InvokePowerShell(runspace); } else { return; } } catch (PSRemotingTransportException pSRemotingTransportException1) { PSRemotingTransportException pSRemotingTransportException = pSRemotingTransportException1; this.HandleTransportError(pSRemotingTransportException, !flag); } catch (Exception exception1) { Exception exception = exception1; this._tracer.TraceException(exception); invoker.AsyncResult.SetAsCompleted(exception); } } finally { this._currentInvoker = null; this.ResetBusy(); } }
/// <summary> /// Prepare the environment based on the policy and run the powershell /// </summary> /// <param name="invoker"></param> /// <remarks>It is assumed that the caller of this method will spawn appropriate /// thread and so it is fine for us to call the callback on the same thread</remarks> internal void PrepareAndRun(ActivityInvoker invoker) { bool setupSucceeded = false; try { // Transport (PSRemotingTransportException) error can happen during setup/prepare phase, so it is getting assigned before setup phase. // _currentInvoker = invoker; Runspace runspace = null; // Retry for 10 times if runspace is in Broken state // // Runspace can be broken, when a remote runspace is getting closed during the next activity execution, // the close ack is getting timedout and that close ack is received by the newly created remote runspace for // the next activity since stdoutput stream of server process is not cleared/discarded, // that is why during new runspace is in broken state while it is being opened. // for (int i = 1; (i <= 10) && !invoker.IsCancelled; i++) { // prepare the runspace with the necessary // modules and variables here runspace = GetRunspace(true); if (runspace.RunspaceStateInfo.State == RunspaceState.Opened) { break; } System.Threading.Thread.Sleep(i * 200); } if (invoker.IsCancelled) { return; } Debug.Assert((runspace.RunspaceStateInfo.State == RunspaceState.Opened), "Runspace is not in Opened state for running an OOP activity"); if (invoker.Policy.Variables.Count > 0) { // set the variables in the specified runspace _tracer.WriteMessage("BEGIN Setting up variables in runspace ", _runspace.InstanceId.ToString()); SetVariablesFromPolicy(runspace, invoker.Policy.Variables); _tracer.WriteMessage("END Setting up variables in runspace ", _runspace.InstanceId.ToString()); } if (invoker.Policy.Modules.Count > 0) { // attempt loading the modules in the specified runspace _tracer.WriteMessage("BEGIN Setting up runspace from policy ", _runspace.InstanceId.ToString()); ImportModulesFromPolicy(runspace, invoker.Policy.Modules); _tracer.WriteMessage("END Setting up runspace from policy ", _runspace.InstanceId.ToString()); } // Prepare phase is completed without any issues. // setupSucceeded flag is used in HandleTransportError method to enqueue the current activity for retry. // If there is any PSRemotingTransportException during InvokePowershell current activity will not be enqueued to setup failed requests in ActivityHostManager. // setupSucceeded = true; // at this point we assume we have a clean runspace to // run the command // if the runspace is broken then the invocation will // result in an error either ways invoker.InvokePowerShell(runspace); } catch (PSRemotingTransportException transportException) { HandleTransportError(transportException, !setupSucceeded); } catch (Exception e) { // at this point there is an exception other than a // transport exception that is caused by trying to // setup the runspace. Release the asyncresult // accordingly _tracer.TraceException(e); invoker.AsyncResult.SetAsCompleted(e); } finally { _currentInvoker = null; ResetBusy(); } }
internal void RunPowerShellInActivityHost(System.Management.Automation.PowerShell powershell, PSDataCollection<PSObject> input, PSDataCollection<PSObject> output, PSActivityEnvironment policy, ConnectionAsyncResult asyncResult) { ActivityInvoker activityInvoker = new ActivityInvoker(); activityInvoker.Input = input; activityInvoker.Output = output; activityInvoker.Policy = policy; activityInvoker.PowerShell = powershell; activityInvoker.AsyncResult = asyncResult; ActivityInvoker activityInvoker1 = activityInvoker; this._requests.Enqueue(activityInvoker1); this.CheckAndStartServicingThread(); }
private void RunInProcess(ActivityInvoker invoker, ActivityHostProcess process) { if (!invoker.IsCancelled) { process.Busy = true; Interlocked.Increment(ref this._busyHosts); PSOutOfProcessActivityController.PerfCountersMgr.UpdateCounterByValue(PSWorkflowPerformanceCounterSetInfo.CounterSetId, 16, (long)1, true); Tuple<ActivityHostProcess, ActivityInvoker> tuple = new Tuple<ActivityHostProcess, ActivityInvoker>(process, invoker); ThreadPool.QueueUserWorkItem(new WaitCallback(PSOutOfProcessActivityController.RunPowerShellInActivityHostWorker), tuple); return; } else { return; } }
private void ServiceRequests(object state) { ActivityInvoker activityInvoker = null; bool flag = false; while (Interlocked.CompareExchange(ref this._busyHosts, this._configuration.MaxActivityProcesses, this._configuration.MaxActivityProcesses) < this._configuration.MaxActivityProcesses) { Collection <ActivityHostProcess> activityHostProcesses = this._hostProcesses; List <ActivityHostProcess> list = activityHostProcesses.Where <ActivityHostProcess>((ActivityHostProcess process) => process.MarkForRemoval).ToList <ActivityHostProcess>(); foreach (ActivityHostProcess activityHostProcess in list) { this.SafelyDisposeProcess(activityHostProcess); } if (this._failedRequests.Count <= 0) { this._requests.TryDequeue(out activityInvoker); flag = false; } else { this._failedRequests.TryDequeue(out activityInvoker); flag = true; } if (activityInvoker == null) { break; } if (activityInvoker.IsCancelled) { continue; } if (!flag) { PSOutOfProcessActivityController.PerfCountersMgr.UpdateCounterByValue(PSWorkflowPerformanceCounterSetInfo.CounterSetId, 20, (long)-1, true); } else { PSOutOfProcessActivityController.PerfCountersMgr.UpdateCounterByValue(PSWorkflowPerformanceCounterSetInfo.CounterSetId, 18, (long)-1, true); } bool flag1 = false; Collection <ActivityHostProcess> activityHostProcesses1 = this._hostProcesses; IEnumerator <ActivityHostProcess> enumerator = activityHostProcesses1.Where <ActivityHostProcess>((ActivityHostProcess process) => !process.Busy).GetEnumerator(); using (enumerator) { if (enumerator.MoveNext()) { ActivityHostProcess current = enumerator.Current; flag1 = true; this.RunInProcess(activityInvoker, current); } } if (flag1) { continue; } ActivityHostProcess activityHostProcess1 = this.CreateNewActivityHostProcess(); this._hostProcesses.Add(activityHostProcess1); this.RunInProcess(activityInvoker, activityHostProcess1); } Interlocked.CompareExchange(ref this._isServicing, 0, 1); if ((this._failedRequests.Count > 0 || this._requests.Count > 0) && Interlocked.CompareExchange(ref this._busyHosts, this._configuration.MaxActivityProcesses, this._configuration.MaxActivityProcesses) < this._configuration.MaxActivityProcesses) { this.CheckAndStartServicingThread(); } }
/// <summary> /// Method called by servicing thread. This method will run the command in the /// specified process on a separate thread /// </summary> /// <param name="invoker"></param> /// <param name="process"></param> private void RunInProcess(ActivityInvoker invoker, ActivityHostProcess process) { if (invoker.IsCancelled) { return; } process.Busy = true; Interlocked.Increment(ref _busyHosts); PerfCountersMgr.UpdateCounterByValue( PSWorkflowPerformanceCounterSetInfo.CounterSetId, PSWorkflowPerformanceCounterIds.ActivityHostMgrBusyProcessesCount); // Adding Tuple object with HostProcess and ActivityInvoker to ThreadPool.QueueUserWorkItem // Back reference on ActivityHostProcess in ActivityInvoker is removed // Tuple<ActivityHostProcess, ActivityInvoker> tupleProcessAndInvoker = new Tuple<ActivityHostProcess, ActivityInvoker>(process, invoker); ThreadPool.QueueUserWorkItem(RunPowerShellInActivityHostWorker, tupleProcessAndInvoker); }
/// <summary> /// Begin invocation of command specified in activity /// </summary> /// <param name="command">pipeline of command to execute</param> /// <param name="input">input collection</param> /// <param name="output">output collection</param> /// <param name="policy">policy to use for the activity</param> /// <param name="callback">optional callback</param> /// <param name="state">optional caller specified state</param> /// <returns>IAsyncResult</returns> internal IAsyncResult BeginInvokePowerShell(System.Management.Automation.PowerShell command, PSDataCollection<PSObject> input, PSDataCollection<PSObject> output, PSActivityEnvironment policy, AsyncCallback callback, object state) { if (command == null) { throw new ArgumentNullException("command"); } ConnectionAsyncResult result = new ConnectionAsyncResult(state, callback, command.InstanceId); _structuredTracer.OutOfProcessRunspaceStarted(command.ToString()); ActivityInvoker invoker = new ActivityInvoker { Input = input, Output = output, Policy = policy, PowerShell = command, AsyncResult = result }; result.Invoker = invoker; _requests.Enqueue(invoker); PerfCountersMgr.UpdateCounterByValue( PSWorkflowPerformanceCounterSetInfo.CounterSetId, PSWorkflowPerformanceCounterIds.ActivityHostMgrIncomingRequestsPerSec); PerfCountersMgr.UpdateCounterByValue( PSWorkflowPerformanceCounterSetInfo.CounterSetId, PSWorkflowPerformanceCounterIds.ActivityHostMgrPendingRequestsQueueLength); CheckAndStartServicingThread(); return result; }
/// <summary> /// Prepare the environment based on the policy and run the powershell /// </summary> /// <param name="invoker"></param> /// <remarks>It is assumed that the caller of this method will spawn appropriate /// thread and so it is fine for us to call the callback on the same thread</remarks> internal void PrepareAndRun(ActivityInvoker invoker) { bool setupSucceeded = false; try { // Transport (PSRemotingTransportException) error can happen during setup/prepare phase, so it is getting assigned before setup phase. // _currentInvoker = invoker; Runspace runspace = null; // Retry for 10 times if runspace is in Broken state // // Runspace can be broken, when a remote runspace is getting closed during the next activity execution, // the close ack is getting timedout and that close ack is received by the newly created remote runspace for // the next activity since stdoutput stream of server process is not cleared/discarded, // that is why during new runspace is in broken state while it is being opened. // for (int i = 1; (i <= 10) && !invoker.IsCancelled; i++) { // prepare the runspace with the necessary // modules and variables here runspace = GetRunspace(true); if (runspace.RunspaceStateInfo.State == RunspaceState.Opened) break; System.Threading.Thread.Sleep(i*200); } if (invoker.IsCancelled) { return; } Debug.Assert((runspace.RunspaceStateInfo.State == RunspaceState.Opened), "Runspace is not in Opened state for running an OOP activity"); if (invoker.Policy.Variables.Count > 0) { // set the variables in the specified runspace _tracer.WriteMessage("BEGIN Setting up variables in runspace ", _runspace.InstanceId.ToString()); SetVariablesFromPolicy(runspace, invoker.Policy.Variables); _tracer.WriteMessage("END Setting up variables in runspace ", _runspace.InstanceId.ToString()); } if (invoker.Policy.Modules.Count > 0) { // attempt loading the modules in the specified runspace _tracer.WriteMessage("BEGIN Setting up runspace from policy ", _runspace.InstanceId.ToString()); ImportModulesFromPolicy(runspace, invoker.Policy.Modules); _tracer.WriteMessage("END Setting up runspace from policy ", _runspace.InstanceId.ToString()); } // Prepare phase is completed without any issues. // setupSucceeded flag is used in HandleTransportError method to enqueue the current activity for retry. // If there is any PSRemotingTransportException during InvokePowershell current activity will not be enqueued to setup failed requests in ActivityHostManager. // setupSucceeded = true; // at this point we assume we have a clean runspace to // run the command // if the runspace is broken then the invocation will // result in an error either ways invoker.InvokePowerShell(runspace); } catch (PSRemotingTransportException transportException) { HandleTransportError(transportException, !setupSucceeded); } catch (Exception e) { // at this point there is an exception other than a // transport exception that is caused by trying to // setup the runspace. Release the asyncresult // accordingly _tracer.TraceException(e); invoker.AsyncResult.SetAsCompleted(e); } finally { _currentInvoker = null; ResetBusy(); } }