public async Task <WorkerStatus> GetWorkerStatusAsync()
        {
            var workerStatus = new WorkerStatus();

            if (!string.IsNullOrEmpty(_workerCapabilities.GetCapabilityState(RpcWorkerConstants.WorkerStatus)))
            {
                // get the worker's current status
                // this will include the OOP worker's channel latency in the request, which can be used upstream
                // to make scale decisions
                var message = new StreamingMessage
                {
                    RequestId           = Guid.NewGuid().ToString(),
                    WorkerStatusRequest = new WorkerStatusRequest()
                };

                var sw  = ValueStopwatch.StartNew();
                var tcs = new TaskCompletionSource <bool>();
                if (_workerStatusRequests.TryAdd(message.RequestId, tcs))
                {
                    SendStreamingMessage(message);
                    await tcs.Task;
                    var elapsed = sw.GetElapsedTime();
                    workerStatus.Latency = elapsed;
                    _workerChannelLogger.LogDebug($"[HostMonitor] Worker status request took {elapsed.TotalMilliseconds}ms");
                }
            }

            workerStatus.IsReady = IsChannelReadyForInvocations();
            if (_environment.IsWorkerDynamicConcurrencyEnabled())
            {
                workerStatus.LatencyHistory = GetLatencies();
            }

            return(workerStatus);
        }
示例#2
0
        public async Task <WorkerStatus> GetWorkerStatusAsync()
        {
            var workerStatus = new WorkerStatus();

            if (!string.IsNullOrEmpty(_workerCapabilities.GetCapabilityState(RpcWorkerConstants.WorkerStatus)))
            {
                // get the worker's current status
                // this will include the OOP worker's channel latency in the request, which can be used upstream
                // to make scale decisions
                var message = new StreamingMessage
                {
                    RequestId           = Guid.NewGuid().ToString(),
                    WorkerStatusRequest = new WorkerStatusRequest()
                };

                var sw  = Stopwatch.StartNew();
                var tcs = new TaskCompletionSource <bool>();
                if (_workerStatusRequests.TryAdd(message.RequestId, tcs))
                {
                    SendStreamingMessage(message);
                    await tcs.Task;
                    sw.Stop();
                    workerStatus.Latency = sw.Elapsed;
                    _workerChannelLogger.LogDebug($"[HostMonitor] Worker status request took {sw.ElapsedMilliseconds}ms");
                }
            }

            // get the process stats for the worker
            var workerProcessStats = _rpcWorkerProcess.GetStats();

            workerStatus.ProcessStats = workerProcessStats;

            if (workerProcessStats.CpuLoadHistory.Any())
            {
                string formattedLoadHistory   = string.Join(",", workerProcessStats.CpuLoadHistory);
                int    executingFunctionCount = FunctionInputBuffers.Sum(p => p.Value.Count);
                _workerChannelLogger.LogDebug($"[HostMonitor] Worker process stats: EffectiveCores={_environment.GetEffectiveCoresCount()}, ProcessId={_rpcWorkerProcess.Id}, ExecutingFunctions={executingFunctionCount}, CpuLoadHistory=({formattedLoadHistory}), AvgLoad={workerProcessStats.CpuLoadHistory.Average()}, MaxLoad={workerProcessStats.CpuLoadHistory.Max()}");
            }

            return(workerStatus);
        }
示例#3
0
        public static async Task <InvocationRequest> ToRpcInvocationRequest(this ScriptInvocationContext context, ILogger logger, GrpcCapabilities capabilities)
        {
            bool excludeHttpTriggerMetadata = !string.IsNullOrEmpty(capabilities.GetCapabilityState(RpcWorkerConstants.RpcHttpTriggerMetadataRemoved));

            var invocationRequest = new InvocationRequest
            {
                FunctionId   = context.FunctionMetadata.GetFunctionId(),
                InvocationId = context.ExecutionContext.InvocationId.ToString(),
                TraceContext = GetRpcTraceContext(context.Traceparent, context.Tracestate, context.Attributes, logger),
            };

            var rpcValueCache = new Dictionary <object, TypedData>();

            foreach (var input in context.Inputs)
            {
                TypedData rpcValue = null;
                if (input.val == null || !rpcValueCache.TryGetValue(input.val, out rpcValue))
                {
                    rpcValue = await input.val.ToRpc(logger, capabilities);

                    if (input.val != null)
                    {
                        rpcValueCache.Add(input.val, rpcValue);
                    }
                }

                var parameterBinding = new ParameterBinding
                {
                    Name = input.name,
                    Data = rpcValue
                };
                invocationRequest.InputData.Add(parameterBinding);
            }

            foreach (var pair in context.BindingData)
            {
                if (ShouldSkipBindingData(pair, context, excludeHttpTriggerMetadata))
                {
                    continue;
                }

                if (!rpcValueCache.TryGetValue(pair.Value, out TypedData rpcValue))
                {
                    rpcValue = await pair.Value.ToRpc(logger, capabilities);

                    rpcValueCache.Add(pair.Value, rpcValue);
                }

                invocationRequest.TriggerMetadata.Add(pair.Key, rpcValue);
            }

            return(invocationRequest);
        }
 private static bool ShouldUseNullableValueDictionary(GrpcCapabilities capabilities)
 {
     return(!string.IsNullOrEmpty(capabilities.GetCapabilityState(RpcWorkerConstants.UseNullableValueDictionaryForHttp)));
 }
 private static bool ShouldIgnoreEmptyHeaderValues(GrpcCapabilities capabilities)
 {
     return(!string.IsNullOrEmpty(capabilities.GetCapabilityState(RpcWorkerConstants.IgnoreEmptyValuedRpcHttpHeaders)));
 }
 private static bool IsTypedDataCollectionSupported(GrpcCapabilities capabilities)
 {
     return(!string.IsNullOrEmpty(capabilities.GetCapabilityState(RpcWorkerConstants.TypedDataCollection)));
 }
 private static bool IsBodyOnlySupported(GrpcCapabilities capabilities)
 {
     return(!string.IsNullOrEmpty(capabilities.GetCapabilityState(RpcWorkerConstants.RpcHttpBodyOnly)));
 }
 private static bool IsRawBodyBytesRequested(GrpcCapabilities capabilities)
 {
     return(!string.IsNullOrEmpty(capabilities.GetCapabilityState(RpcWorkerConstants.RawHttpBodyBytes)));
 }
示例#9
0
        public static async Task <InvocationRequest> ToRpcInvocationRequest(this ScriptInvocationContext context, ILogger logger, GrpcCapabilities capabilities, bool isSharedMemoryDataTransferEnabled, ISharedMemoryManager sharedMemoryManager)
        {
            bool excludeHttpTriggerMetadata = !string.IsNullOrEmpty(capabilities.GetCapabilityState(RpcWorkerConstants.RpcHttpTriggerMetadataRemoved));

            var invocationRequest = new InvocationRequest
            {
                FunctionId   = context.FunctionMetadata.GetFunctionId(),
                InvocationId = context.ExecutionContext.InvocationId.ToString(),
                TraceContext = GetRpcTraceContext(context.Traceparent, context.Tracestate, context.Attributes, logger),
            };

            SetRetryContext(context, invocationRequest);

            var rpcValueCache = new Dictionary <object, TypedData>();
            Dictionary <object, RpcSharedMemory> sharedMemValueCache = null;
            StringBuilder logBuilder       = null;
            bool          usedSharedMemory = false;

            if (isSharedMemoryDataTransferEnabled)
            {
                sharedMemValueCache = new Dictionary <object, RpcSharedMemory>();
                logBuilder          = new StringBuilder();
            }

            foreach (var input in context.Inputs)
            {
                RpcSharedMemory  sharedMemValue   = null;
                ParameterBinding parameterBinding = null;
                if (isSharedMemoryDataTransferEnabled)
                {
                    // Try to transfer this data over shared memory instead of RPC
                    if (input.val == null || !sharedMemValueCache.TryGetValue(input.val, out sharedMemValue))
                    {
                        sharedMemValue = await input.val.ToRpcSharedMemoryAsync(logger, invocationRequest.InvocationId, sharedMemoryManager);

                        if (input.val != null)
                        {
                            sharedMemValueCache.Add(input.val, sharedMemValue);
                        }
                    }
                }

                if (sharedMemValue != null)
                {
                    // Data was successfully transferred over shared memory; create a ParameterBinding accordingly
                    parameterBinding = new ParameterBinding
                    {
                        Name            = input.name,
                        RpcSharedMemory = sharedMemValue
                    };

                    usedSharedMemory = true;
                    logBuilder.AppendFormat("{0}:{1},", input.name, sharedMemValue.Count);
                }
                else
                {
                    // Data was not transferred over shared memory (either disabled, type not supported or some error); resort to RPC
                    TypedData rpcValue = null;
                    if (input.val == null || !rpcValueCache.TryGetValue(input.val, out rpcValue))
                    {
                        rpcValue = await input.val.ToRpc(logger, capabilities);

                        if (input.val != null)
                        {
                            rpcValueCache.Add(input.val, rpcValue);
                        }
                    }

                    parameterBinding = new ParameterBinding
                    {
                        Name = input.name,
                        Data = rpcValue
                    };
                }

                invocationRequest.InputData.Add(parameterBinding);
            }

            foreach (var pair in context.BindingData)
            {
                if (ShouldSkipBindingData(pair, context, excludeHttpTriggerMetadata))
                {
                    continue;
                }

                if (!rpcValueCache.TryGetValue(pair.Value, out TypedData rpcValue))
                {
                    rpcValue = await pair.Value.ToRpc(logger, capabilities);

                    rpcValueCache.Add(pair.Value, rpcValue);
                }

                invocationRequest.TriggerMetadata.Add(pair.Key, rpcValue);
            }

            if (usedSharedMemory)
            {
                logger.LogDebug("Shared memory usage for request of invocation Id: {Id} is {SharedMemoryUsage}", invocationRequest.InvocationId, logBuilder.ToString());
            }

            return(invocationRequest);
        }