/// <summary> /// Checkout an idle PowerShellManager instance in a non-blocking asynchronous way. /// </summary> internal PowerShellManager CheckoutIdleWorker(StreamingMessage request, AzFunctionInfo functionInfo) { PowerShellManager psManager = null; string requestId = request.RequestId; string invocationId = request.InvocationRequest?.InvocationId; // If the pool has an idle one, just use it. if (!_pool.TryTake(out psManager)) { // The pool doesn't have an idle one. if (_poolSize < _upperBound && Interlocked.Increment(ref _poolSize) <= _upperBound) { // If the pool hasn't reached its bounded capacity yet, then // we create a new item and return it. var logger = new RpcLogger(_msgStream); logger.SetContext(requestId, invocationId); psManager = new PowerShellManager(logger); } else { // If the pool has reached its bounded capacity, then the thread // should be blocked until an idle one becomes available. psManager = _pool.Take(); } } // Register the function with the Runspace before returning the idle PowerShellManager. FunctionMetadata.RegisterFunctionMetadata(psManager.InstanceId, functionInfo); psManager.Logger.SetContext(requestId, invocationId); return(psManager); }
/// <summary> /// Populate the pool with the very first PowerShellManager instance. /// We instantiate PowerShellManager instances in a lazy way, starting from size 1 and increase the number of workers as needed. /// </summary> internal void Initialize(PowerShell pwsh) { var logger = new RpcLogger(_msgStream); var psManager = new PowerShellManager(logger, pwsh); _pool.Add(psManager); _poolSize = 1; }
/// <summary> /// Populate the pool with the very first PowerShellManager instance. /// We instantiate PowerShellManager instances in a lazy way, starting from size 1 and increase the number of workers as needed. /// </summary> internal void Initialize(PowerShell pwsh) { var logger = _createLogger(); var psManager = new PowerShellManager(logger, pwsh); _pool.Add(psManager); _poolSize = 1; }
/// <summary> /// Return a used PowerShellManager instance to the pool. /// </summary> internal void ReclaimUsedWorker(PowerShellManager psManager) { if (psManager != null) { // Unregister the Runspace before reclaiming the used PowerShellManager. FunctionMetadata.UnregisterFunctionMetadata(psManager.InstanceId); psManager.Logger.ResetContext(); _pool.Add(psManager); } }
/// <summary> /// Checkout an idle PowerShellManager instance in a non-blocking asynchronous way. /// </summary> internal PowerShellManager CheckoutIdleWorker( string requestId, string invocationId, string functionName, ReadOnlyDictionary <string, ReadOnlyBindingInfo> outputBindings) { PowerShellManager psManager = null; // If the pool has an idle one, just use it. if (!_pool.TryTake(out psManager)) { // The pool doesn't have an idle one. if (_poolSize < UpperBound) { int id = Interlocked.Increment(ref _poolSize); if (id <= UpperBound) { // If the pool hasn't reached its bounded capacity yet, then // we create a new item and return it. var logger = CreateLoggerWithContext(requestId, invocationId); psManager = new PowerShellManager(logger, id); RpcLogger.WriteSystemLog(LogLevel.Trace, string.Format(PowerShellWorkerStrings.LogNewPowerShellManagerCreated, id.ToString())); } } if (psManager == null) { var logger = CreateLoggerWithContext(requestId, invocationId); logger.Log(isUserOnlyLog: true, LogLevel.Warning, string.Format(PowerShellWorkerStrings.FunctionQueuingRequest, functionName)); // If the pool has reached its bounded capacity, then the thread // should be blocked until an idle one becomes available. psManager = _pool.Take(); } } psManager.Logger.SetContext(requestId, invocationId); // Finish the initialization if not yet. // This applies only to the very first PowerShellManager instance, whose initialization was deferred. psManager.Initialize(); // Register the function with the Runspace before returning the idle PowerShellManager. FunctionMetadata.RegisterFunctionMetadata(psManager.InstanceId, outputBindings); return(psManager); }
/// <summary> /// Checkout an idle PowerShellManager instance in a non-blocking asynchronous way. /// </summary> internal PowerShellManager CheckoutIdleWorker(StreamingMessage request, AzFunctionInfo functionInfo) { PowerShellManager psManager = null; string requestId = request.RequestId; string invocationId = request.InvocationRequest?.InvocationId; // If the pool has an idle one, just use it. if (!_pool.TryTake(out psManager)) { // The pool doesn't have an idle one. if (_poolSize < _upperBound) { int id = Interlocked.Increment(ref _poolSize); if (id <= _upperBound) { // If the pool hasn't reached its bounded capacity yet, then // we create a new item and return it. var logger = new RpcLogger(_msgStream); logger.SetContext(requestId, invocationId); psManager = new PowerShellManager(logger, id); RpcLogger.WriteSystemLog(LogLevel.Trace, string.Format(PowerShellWorkerStrings.LogNewPowerShellManagerCreated, id.ToString())); } } if (psManager == null) { // If the pool has reached its bounded capacity, then the thread // should be blocked until an idle one becomes available. psManager = _pool.Take(); } } // Finish the initialization if not yet. // This applies only to the very first PowerShellManager instance, whose initialization was deferred. psManager.Initialize(); // Register the function with the Runspace before returning the idle PowerShellManager. FunctionMetadata.RegisterFunctionMetadata(psManager.InstanceId, functionInfo); psManager.Logger.SetContext(requestId, invocationId); return(psManager); }