public async Task ShutdownChannelsIfExistsAsync_StopsWorkerInvocations() { IRpcWorkerChannel javaWorkerChannel = CreateTestChannel(RpcWorkerConstants.JavaLanguageWorkerName); Guid invocationId = Guid.NewGuid(); ScriptInvocationContext scriptInvocationContext = new ScriptInvocationContext() { ExecutionContext = new ExecutionContext() { InvocationId = invocationId } }; (javaWorkerChannel as TestRpcWorkerChannel).SendInvocationRequest(scriptInvocationContext); Assert.True(javaWorkerChannel.IsExecutingInvocation(invocationId.ToString())); Exception workerException = new Exception("Worker exception"); // Channel is removed immediately but is not failed immediately await _rpcWorkerChannelManager.ShutdownChannelIfExistsAsync(RpcWorkerConstants.JavaLanguageWorkerName, javaWorkerChannel.Id, workerException); Assert.Null(_rpcWorkerChannelManager.GetChannels(RpcWorkerConstants.JavaLanguageWorkerName)); var initializedChannel = await _rpcWorkerChannelManager.GetChannelAsync(RpcWorkerConstants.JavaLanguageWorkerName); Assert.Null(initializedChannel); // Execution will be terminated in the background - giving it 10 seconds await TestHelpers.Await(() => { return(!javaWorkerChannel.IsExecutingInvocation(invocationId.ToString())); }, 10000); Assert.False(javaWorkerChannel.IsExecutingInvocation(invocationId.ToString())); }
public static InvocationRequest ToRpcInvocationRequest(this ScriptInvocationContext context, bool isTriggerMetadataPopulatedByWorker, ILogger logger, Capabilities capabilities) { InvocationRequest invocationRequest = new InvocationRequest() { FunctionId = context.FunctionMetadata.FunctionId, InvocationId = context.ExecutionContext.InvocationId.ToString(), TraceContext = GetRpcTraceContext(context.Traceparent, context.Tracestate, context.Attributes, logger), }; foreach (var pair in context.BindingData) { if (pair.Value != null) { if ((pair.Value is HttpRequest) && isTriggerMetadataPopulatedByWorker) { continue; } invocationRequest.TriggerMetadata.Add(pair.Key, pair.Value.ToRpc(logger, capabilities)); } } foreach (var input in context.Inputs) { invocationRequest.InputData.Add(new ParameterBinding() { Name = input.name, Data = input.val.ToRpc(logger, capabilities) }); } return(invocationRequest); }
public async Task Drain_Verify() { var resultSource = new TaskCompletionSource <ScriptInvocationResult>(); Guid invocationId = Guid.NewGuid(); RpcWorkerChannel channel = new RpcWorkerChannel( _workerId, _eventManager, _testWorkerConfig, _mockrpcWorkerProcess.Object, _logger, _metricsLogger, 0, _testEnvironment, _hostOptionsMonitor); channel.SetupFunctionInvocationBuffers(GetTestFunctionsList("node")); ScriptInvocationContext scriptInvocationContext = GetTestScriptInvocationContext(invocationId, resultSource); await channel.SendInvocationRequest(scriptInvocationContext); Task result = channel.DrainInvocationsAsync(); Assert.NotEqual(result.Status, TaskStatus.RanToCompletion); channel.InvokeResponse(new InvocationResponse { InvocationId = invocationId.ToString(), Result = new StatusResult { Status = StatusResult.Types.Status.Success }, }); await result; Assert.Equal(result.Status, TaskStatus.RanToCompletion); }
internal void SendInvocationRequest(ScriptInvocationContext context) { try { if (_functionLoadErrors.ContainsKey(context.FunctionMetadata.FunctionId)) { _workerChannelLogger.LogDebug($"Function {context.FunctionMetadata.Name} failed to load"); context.ResultSource.TrySetException(_functionLoadErrors[context.FunctionMetadata.FunctionId]); _executingInvocations.TryRemove(context.ExecutionContext.InvocationId.ToString(), out ScriptInvocationContext _); } else { if (context.CancellationToken.IsCancellationRequested) { context.ResultSource.SetCanceled(); return; } InvocationRequest invocationRequest = context.ToRpcInvocationRequest(IsTriggerMetadataPopulatedByWorker(), _workerChannelLogger, _workerCapabilities); _executingInvocations.TryAdd(invocationRequest.InvocationId, context); SendStreamingMessage(new StreamingMessage { InvocationRequest = invocationRequest }); } } catch (Exception invokeEx) { context.ResultSource.TrySetException(invokeEx); } }
internal async Task SendInvocationRequest(ScriptInvocationContext context) { try { if (_functionLoadErrors.ContainsKey(context.FunctionMetadata.GetFunctionId())) { _workerChannelLogger.LogDebug($"Function {context.FunctionMetadata.Name} failed to load"); context.ResultSource.TrySetException(_functionLoadErrors[context.FunctionMetadata.GetFunctionId()]); _executingInvocations.TryRemove(context.ExecutionContext.InvocationId.ToString(), out ScriptInvocationContext _); } else { if (context.CancellationToken.IsCancellationRequested) { context.ResultSource.SetCanceled(); return; } var invocationRequest = await context.ToRpcInvocationRequest(_workerChannelLogger, _workerCapabilities, _isSharedMemoryDataTransferEnabled, _sharedMemoryManager); _executingInvocations.TryAdd(invocationRequest.InvocationId, context); SendStreamingMessage(new StreamingMessage { InvocationRequest = invocationRequest }); } } catch (Exception invokeEx) { context.ResultSource.TrySetException(invokeEx); } }
public void TestSetRetryContext_Retry() { ScriptInvocationContext context = new ScriptInvocationContext() { ExecutionContext = new ExecutionContext() { RetryContext = new Host.RetryContext() { RetryCount = 1, MaxRetryCount = 2, Exception = new Exception("test") } } }; HttpScriptInvocationContext testContext = new HttpScriptInvocationContext() { Data = new Dictionary <string, object>(), Metadata = new Dictionary <string, object>() }; ScriptInvocationContextExtensions.SetRetryContext(context, testContext); var retryContext = (RetryContext)testContext.Metadata["RetryContext"]; Assert.NotNull(retryContext); Assert.Equal(retryContext.RetryCount, context.ExecutionContext.RetryContext.RetryCount); Assert.Equal(retryContext.MaxRetryCount, context.ExecutionContext.RetryContext.MaxRetryCount); Assert.NotNull(retryContext.Exception); }
public void SendInvocationRequest_IsInExecutingInvocation() { ScriptInvocationContext scriptInvocationContext = GetTestScriptInvocationContext(Guid.NewGuid(), null); _workerChannel.SendInvocationRequest(scriptInvocationContext); Assert.True(_workerChannel.IsExecutingInvocation(scriptInvocationContext.ExecutionContext.InvocationId.ToString())); Assert.False(_workerChannel.IsExecutingInvocation(Guid.NewGuid().ToString())); }
public Task InvokeAsync(ScriptInvocationContext scriptInvocationContext) { if (scriptInvocationContext.FunctionMetadata.IsHttpInAndOutFunction) { return(ProcessHttpInAndOutInvocationRequest(scriptInvocationContext)); } return(ProcessDefaultInvocationRequest(scriptInvocationContext)); }
internal void SendInvocationRequest(ScriptInvocationContext context) { try { if (_functionLoadErrors.ContainsKey(context.FunctionMetadata.FunctionId)) { _workerChannelLogger.LogDebug($"Function {context.FunctionMetadata.Name} failed to load"); context.ResultSource.TrySetException(_functionLoadErrors[context.FunctionMetadata.FunctionId]); _executingInvocations.TryRemove(context.ExecutionContext.InvocationId.ToString(), out ScriptInvocationContext _); } else { if (context.CancellationToken.IsCancellationRequested) { context.ResultSource.SetCanceled(); return; } var functionMetadata = context.FunctionMetadata; InvocationRequest invocationRequest = new InvocationRequest() { FunctionId = functionMetadata.FunctionId, InvocationId = context.ExecutionContext.InvocationId.ToString(), }; foreach (var pair in context.BindingData) { if (pair.Value != null) { if ((pair.Value is HttpRequest) && IsTriggerMetadataPopulatedByWorker()) { continue; } invocationRequest.TriggerMetadata.Add(pair.Key, pair.Value.ToRpc(_workerChannelLogger, _workerCapabilities)); } } foreach (var input in context.Inputs) { invocationRequest.InputData.Add(new ParameterBinding() { Name = input.name, Data = input.val.ToRpc(_workerChannelLogger, _workerCapabilities) }); } _executingInvocations.TryAdd(invocationRequest.InvocationId, context); SendStreamingMessage(new StreamingMessage { InvocationRequest = invocationRequest }); } } catch (Exception invokeEx) { context.ResultSource.TrySetException(invokeEx); } }
private static async Task LogHttpContent(ScriptInvocationContext scriptInvocationContext, HttpContent httpContent) { string stringContent = await GetHttpContentAsString(httpContent); if (!string.IsNullOrEmpty(stringContent)) { scriptInvocationContext.Logger.LogTrace($"{stringContent}"); } }
public void SendInvocationRequest_PublishesOutboundEvent() { ScriptInvocationContext scriptInvocationContext = GetTestScriptInvocationContext(Guid.NewGuid(), null); _workerChannel.SendInvocationRequest(scriptInvocationContext); var traces = _logger.GetLogMessages(); Assert.True(traces.Any(m => string.Equals(m.FormattedMessage, _expectedLogMsg))); }
public void TestSetRetryContext_NoRetry() { ScriptInvocationContext context = new ScriptInvocationContext() { ExecutionContext = new ExecutionContext() }; InvocationRequest request = new InvocationRequest(); Grpc.ScriptInvocationContextExtensions.SetRetryContext(context, request); Assert.Null(request.RetryContext); }
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); }
internal async Task ProcessHttpInAndOutInvocationRequest(ScriptInvocationContext scriptInvocationContext) { _logger.LogDebug("Will invoke simple httpTrigger function: '{functionName}' invocationId: '{invocationId}'", scriptInvocationContext.FunctionMetadata.Name, scriptInvocationContext.ExecutionContext.InvocationId); ScriptInvocationResult scriptInvocationResult = new ScriptInvocationResult() { Outputs = new Dictionary <string, object>() }; HttpRequestMessage httpRequestMessage = null; (string name, DataType type, object request)input = scriptInvocationContext.Inputs.First(); HttpRequest httpRequest = input.request as HttpRequest; if (httpRequest == null) { throw new InvalidOperationException($"HttpTrigger value for: `{input.name}` is null"); } try { // Build HttpRequestMessage from HttpTrigger binding HttpRequestMessageFeature httpRequestMessageFeature = new HttpRequestMessageFeature(httpRequest.HttpContext); httpRequestMessage = httpRequestMessageFeature.HttpRequestMessage; AddRequestHeadersAndSetRequestUri(httpRequestMessage, scriptInvocationContext.FunctionMetadata.Name, scriptInvocationContext.ExecutionContext.InvocationId.ToString()); // Populate query params from httpTrigger string httpWorkerUri = QueryHelpers.AddQueryString(httpRequestMessage.RequestUri.ToString(), httpRequest.GetQueryCollectionAsDictionary()); httpRequestMessage.RequestUri = new Uri(httpWorkerUri); _logger.LogDebug("Sending http request message for simple httpTrigger function: '{functionName}' invocationId: '{invocationId}'", scriptInvocationContext.FunctionMetadata.Name, scriptInvocationContext.ExecutionContext.InvocationId); HttpResponseMessage invocationResponse = await _httpClient.SendAsync(httpRequestMessage); _logger.LogDebug("Received http response for simple httpTrigger function: '{functionName}' invocationId: '{invocationId}'", scriptInvocationContext.FunctionMetadata.Name, scriptInvocationContext.ExecutionContext.InvocationId); BindingMetadata httpOutputBinding = scriptInvocationContext.FunctionMetadata.OutputBindings.FirstOrDefault(); if (httpOutputBinding != null) { // handle http output binding scriptInvocationResult.Outputs.Add(httpOutputBinding.Name, invocationResponse); // handle $return scriptInvocationResult.Return = invocationResponse; } scriptInvocationContext.ResultSource.SetResult(scriptInvocationResult); } catch (Exception responseEx) { scriptInvocationContext.ResultSource.TrySetException(responseEx); } }
public async Task SendInvocationRequest_InputsTransferredOverSharedMemory() { EnableSharedMemoryDataTransfer(); // Send invocation which will be using RpcSharedMemory for the inputs ScriptInvocationContext scriptInvocationContext = GetTestScriptInvocationContextWithSharedMemoryInputs(Guid.NewGuid(), null); await _workerChannel.SendInvocationRequest(scriptInvocationContext); var traces = _logger.GetLogMessages(); Assert.True(traces.Any(m => string.Equals(m.FormattedMessage, _expectedLogMsg))); }
internal static void SetRetryContext(ScriptInvocationContext scriptInvocationContext, HttpScriptInvocationContext httpScriptInvocationContext) { if (scriptInvocationContext.ExecutionContext.RetryContext != null) { var retryContext = scriptInvocationContext.ExecutionContext.RetryContext; httpScriptInvocationContext.Metadata["RetryContext"] = new RetryContext() { MaxRetryCount = retryContext.MaxRetryCount, RetryCount = retryContext.RetryCount, Exception = retryContext.Exception, }; } }
public Task InvokeAsync(ScriptInvocationContext scriptInvocationContext) { if (scriptInvocationContext.FunctionMetadata.IsHttpInAndOutFunction()) { // type is empty for httpWorker section. EnableForwardingHttpRequest is opt-in for custom handler section. if (_httpWorkerOptions.Type == CustomHandlerType.None || _httpWorkerOptions.EnableForwardingHttpRequest) { return(ProcessHttpInAndOutInvocationRequest(scriptInvocationContext)); } return(ProcessDefaultInvocationRequest(scriptInvocationContext)); } return(ProcessDefaultInvocationRequest(scriptInvocationContext)); }
public void InFlight_Functions_FailedWithException() { var resultSource = new TaskCompletionSource <ScriptInvocationResult>(); ScriptInvocationContext scriptInvocationContext = GetTestScriptInvocationContext(Guid.NewGuid(), resultSource); _workerChannel.SendInvocationRequest(scriptInvocationContext); Assert.True(_workerChannel.IsExecutingInvocation(scriptInvocationContext.ExecutionContext.InvocationId.ToString())); Exception workerException = new Exception("worker failed"); _workerChannel.TryFailExecutions(workerException); Assert.False(_workerChannel.IsExecutingInvocation(scriptInvocationContext.ExecutionContext.InvocationId.ToString())); Assert.Equal(TaskStatus.Faulted, resultSource.Task.Status); Assert.Equal(workerException, resultSource.Task.Exception.InnerException); }
internal async Task ProcessHttpInAndOutInvocationRequest(ScriptInvocationContext scriptInvocationContext) { _logger.LogDebug("Will invoke simple httpTrigger function: '{functionName}' invocationId: '{invocationId}'", scriptInvocationContext.FunctionMetadata.Name, scriptInvocationContext.ExecutionContext.InvocationId); ScriptInvocationResult scriptInvocationResult = new ScriptInvocationResult() { Outputs = new Dictionary <string, object>() }; (string name, DataType type, object request)input = scriptInvocationContext.Inputs.First(); HttpRequest httpRequest = input.request as HttpRequest; if (httpRequest == null) { throw new InvalidOperationException($"HttpTrigger value for: `{input.name}` is null"); } try { string uriPathValue = GetPathValue(_httpWorkerOptions, scriptInvocationContext.FunctionMetadata.Name, httpRequest); string uri = BuildAndGetUri(uriPathValue); using (HttpRequestMessage httpRequestMessage = httpRequest.ToHttpRequestMessage(uri)) { AddHeaders(httpRequestMessage, scriptInvocationContext.ExecutionContext.InvocationId.ToString()); _logger.LogDebug("Forwarding http request for httpTrigger function: '{functionName}' invocationId: '{invocationId}'", scriptInvocationContext.FunctionMetadata.Name, scriptInvocationContext.ExecutionContext.InvocationId); HttpResponseMessage invocationResponse = await _httpClient.SendAsync(httpRequestMessage); _logger.LogDebug("Received http response for httpTrigger function: '{functionName}' invocationId: '{invocationId}'", scriptInvocationContext.FunctionMetadata.Name, scriptInvocationContext.ExecutionContext.InvocationId); BindingMetadata httpOutputBinding = scriptInvocationContext.FunctionMetadata.OutputBindings.FirstOrDefault(); if (httpOutputBinding != null) { // handle http output binding scriptInvocationResult.Outputs.Add(httpOutputBinding.Name, invocationResponse); // handle $return scriptInvocationResult.Return = invocationResponse; } scriptInvocationContext.ResultSource.SetResult(scriptInvocationResult); } } catch (Exception responseEx) { scriptInvocationContext.ResultSource.TrySetException(responseEx); } }
public async Task InvokeAsync(ScriptInvocationContext invocationContext) { try { IEnumerable <ILanguageWorkerChannel> workerChannels = GetInitializedWorkerChannels(); var languageWorkerChannel = _functionDispatcherLoadBalancer.GetLanguageWorkerChannel(workerChannels, _maxProcessCount); BufferBlock <ScriptInvocationContext> bufferBlock = await GetFunctionInvocationBufferBlock(languageWorkerChannel, invocationContext.FunctionMetadata.FunctionId); _logger.LogDebug("Posting invocation id:{InvocationId} on workerId:{workerChannelId}", invocationContext.ExecutionContext.InvocationId, languageWorkerChannel.Id); languageWorkerChannel.FunctionInputBuffers[invocationContext.FunctionMetadata.FunctionId].Post(invocationContext); } catch (Exception invokeEx) { invocationContext.ResultSource.TrySetException(invokeEx); } }
internal async Task ProcessDefaultInvocationRequest(ScriptInvocationContext scriptInvocationContext) { try { HttpScriptInvocationContext httpScriptInvocationContext = await scriptInvocationContext.ToHttpScriptInvocationContext(); string uri = BuildAndGetUri(scriptInvocationContext.FunctionMetadata.Name); // Build httpRequestMessage from scriptInvocationContext using (HttpRequestMessage httpRequestMessage = httpScriptInvocationContext.ToHttpRequestMessage(uri)) { AddHeaders(httpRequestMessage, scriptInvocationContext.ExecutionContext.InvocationId.ToString()); _logger.LogDebug("Sending http request for function:{functionName} invocationId:{invocationId}", scriptInvocationContext.FunctionMetadata.Name, scriptInvocationContext.ExecutionContext.InvocationId); HttpResponseMessage response = await _httpClient.SendAsync(httpRequestMessage); _logger.LogDebug("Received http response for function:{functionName} invocationId:{invocationId}", scriptInvocationContext.FunctionMetadata.Name, scriptInvocationContext.ExecutionContext.InvocationId); // Only process output bindings if response is succeess code response.EnsureSuccessStatusCode(); HttpScriptInvocationResult httpScriptInvocationResult = await response.Content.ReadAsAsync <HttpScriptInvocationResult>(); if (httpScriptInvocationResult != null) { if (httpScriptInvocationResult.Outputs == null || !httpScriptInvocationResult.Outputs.Any()) { _logger.LogWarning("Outputs not set on http response for invocationId:{invocationId}", scriptInvocationContext.ExecutionContext.InvocationId); } if (httpScriptInvocationResult.ReturnValue == null) { _logger.LogWarning("ReturnValue not set on http response for invocationId:{invocationId}", scriptInvocationContext.ExecutionContext.InvocationId); } ProcessLogsFromHttpResponse(scriptInvocationContext, httpScriptInvocationResult); ScriptInvocationResult scriptInvocationResult = httpScriptInvocationResult.ToScriptInvocationResult(scriptInvocationContext); scriptInvocationContext.ResultSource.SetResult(scriptInvocationResult); } } } catch (Exception responseEx) { scriptInvocationContext.ResultSource.TrySetException(responseEx); } }
public Task <string> Get(int id) { if (_languageWorkerChannel == null) { _languageWorkerChannel = _functionDispatcher.WorkerChannels.FirstOrDefault(); } ScriptInvocationContext invocationContext = new ScriptInvocationContext() { FunctionId = id.ToString(), InvocationId = Guid.NewGuid().ToString(), ResultSource = new TaskCompletionSource <string>() }; _languageWorkerChannel.SendInvocationRequest(invocationContext); return(invocationContext.ResultSource.Task); //return $"{id}-succeeed-{invocationContext.InvocationId}"; }
public async Task InvokeAsync(ScriptInvocationContext invocationContext) { // This could throw if no initialized workers are found. Shut down instance and retry. IEnumerable <IRpcWorkerChannel> workerChannels = await GetInitializedWorkerChannelsAsync(); var rpcWorkerChannel = _functionDispatcherLoadBalancer.GetLanguageWorkerChannel(workerChannels, _maxProcessCount); if (rpcWorkerChannel.FunctionInputBuffers.TryGetValue(invocationContext.FunctionMetadata.GetFunctionId(), out BufferBlock <ScriptInvocationContext> bufferBlock)) { _logger.LogTrace("Posting invocation id:{InvocationId} on workerId:{workerChannelId}", invocationContext.ExecutionContext.InvocationId, rpcWorkerChannel.Id); rpcWorkerChannel.FunctionInputBuffers[invocationContext.FunctionMetadata.GetFunctionId()].Post(invocationContext); } else { throw new InvalidOperationException($"Function:{invocationContext.FunctionMetadata.Name} is not loaded by the language worker: {rpcWorkerChannel.Id}"); } }
public void TestSetRetryContext_NoRetry() { ScriptInvocationContext scriptInvocationContext = new ScriptInvocationContext() { ExecutionContext = new ExecutionContext() }; HttpScriptInvocationContext testContext = new HttpScriptInvocationContext() { Data = new Dictionary <string, object>(), Metadata = new Dictionary <string, object>() }; ScriptInvocationContextExtensions.SetRetryContext(scriptInvocationContext, testContext); Assert.Empty(testContext.Metadata); }
public void Invoke(ScriptInvocationContext context) { if (_functionLoadErrors.ContainsKey(context.FunctionMetadata.FunctionId)) { _logger.LogTrace($"Function {context.FunctionMetadata.Name} failed to load"); context.ResultSource.TrySetException(_functionLoadErrors[context.FunctionMetadata.FunctionId]); _executingInvocations.TryRemove(context.ExecutionContext.InvocationId.ToString(), out ScriptInvocationContext _); } else { if (context.CancellationToken.IsCancellationRequested) { context.ResultSource.SetCanceled(); return; } var functionMetadata = context.FunctionMetadata; InvocationRequest invocationRequest = new InvocationRequest() { FunctionId = functionMetadata.FunctionId, InvocationId = context.ExecutionContext.InvocationId.ToString(), }; foreach (var pair in context.BindingData) { invocationRequest.TriggerMetadata.Add(pair.Key, pair.Value.ToRpc()); } foreach (var input in context.Inputs) { invocationRequest.InputData.Add(new ParameterBinding() { Name = input.name, Data = input.val.ToRpc() }); } _executingInvocations.TryAdd(invocationRequest.InvocationId, context); Send(new StreamingMessage { InvocationRequest = invocationRequest }); } }
private async Task <HttpResponseMessage> SendInvocationRequestAsync(ScriptInvocationContext scriptInvocationContext, HttpRequestMessage httpRequestMessage) { // Only log Request / Response when running locally if (_enableRequestTracing) { scriptInvocationContext.Logger.LogTrace($"Invocation Request:{httpRequestMessage}"); await TraceHttpContent(httpRequestMessage.Content, scriptInvocationContext.Logger); } _logger.LogDebug("Sending http request for function:{functionName} invocationId:{invocationId}", scriptInvocationContext.FunctionMetadata.Name, scriptInvocationContext.ExecutionContext.InvocationId); HttpResponseMessage invocationResponse = await _httpClient.SendAsync(httpRequestMessage); if (_enableRequestTracing) { scriptInvocationContext.Logger.LogTrace($"Invocation Response:{invocationResponse}"); await TraceHttpContent(invocationResponse.Content, scriptInvocationContext.Logger); } _logger.LogDebug("Received http response for httpTrigger function: '{functionName}' invocationId: '{invocationId}'", scriptInvocationContext.FunctionMetadata.Name, scriptInvocationContext.ExecutionContext.InvocationId); return(invocationResponse); }
private async Task <HttpResponseMessage> SendInvocationRequestAsync(ScriptInvocationContext scriptInvocationContext, HttpRequestMessage httpRequestMessage) { // Only log Request / Response when running locally if (_enableRequestTracing) { scriptInvocationContext.Logger.LogTrace($"Invocation Request:{httpRequestMessage}"); await LogHttpContent(scriptInvocationContext, httpRequestMessage.Content); } _logger.CustomHandlerSendingInvocation(scriptInvocationContext.FunctionMetadata.Name, scriptInvocationContext.ExecutionContext.InvocationId); HttpResponseMessage invocationResponse = await _httpClient.SendAsync(httpRequestMessage); if (_enableRequestTracing) { scriptInvocationContext.Logger.LogTrace($"Invocation Response:{invocationResponse}"); await LogHttpContent(scriptInvocationContext, invocationResponse.Content); } _logger.CustomHandlerReceivedInvocationResponse(scriptInvocationContext.FunctionMetadata.Name, scriptInvocationContext.ExecutionContext.InvocationId); return(invocationResponse); }
public void Invoke(ScriptInvocationContext invocationContext) { try { IEnumerable <ILanguageWorkerChannel> workerChannels = GetInitializedWorkerChannels(); var languageWorkerChannel = _functionDispatcherLoadBalancer.GetLanguageWorkerChannel(workerChannels, _maxProcessCount); if (languageWorkerChannel.FunctionInputBuffers.TryGetValue(invocationContext.FunctionMetadata.FunctionId, out BufferBlock <ScriptInvocationContext> bufferBlock)) { _logger.LogDebug("Posting invocation id:{InvocationId} on workerId:{workerChannelId}", invocationContext.ExecutionContext.InvocationId, languageWorkerChannel.Id); languageWorkerChannel.FunctionInputBuffers[invocationContext.FunctionMetadata.FunctionId].Post(invocationContext); } else { throw new InvalidOperationException($"Function:{invocationContext.FunctionMetadata.Name} is not loaded by the language worker: {languageWorkerChannel.Id}"); } } catch (Exception invokeEx) { invocationContext.ResultSource.TrySetException(invokeEx); } }
internal static void SetRetryContext(ScriptInvocationContext context, InvocationRequest invocationRequest) { if (context.ExecutionContext.RetryContext != null) { invocationRequest.RetryContext = new RetryContext() { RetryCount = context.ExecutionContext.RetryContext.RetryCount, MaxRetryCount = context.ExecutionContext.RetryContext.MaxRetryCount }; // RetryContext.Exception should not be null, check just in case if (context.ExecutionContext.RetryContext.Exception != null) { invocationRequest.RetryContext.Exception = new RpcException() { Message = ExceptionFormatter.GetFormattedException(context.ExecutionContext.RetryContext.Exception), // merge message from InnerException StackTrace = context.ExecutionContext.RetryContext.Exception.StackTrace ?? string.Empty, Source = context.ExecutionContext.RetryContext.Exception.Source ?? string.Empty }; } } }
internal void ProcessLogsFromHttpResponse(ScriptInvocationContext scriptInvocationContext, HttpScriptInvocationResult invocationResult) { if (scriptInvocationContext == null) { throw new ArgumentNullException(nameof(scriptInvocationContext)); } if (invocationResult == null) { throw new ArgumentNullException(nameof(invocationResult)); } if (invocationResult.Logs != null) { // Restore the execution context from the original invocation. This allows AsyncLocal state to flow to loggers. System.Threading.ExecutionContext.Run(scriptInvocationContext.AsyncExecutionContext, (s) => { foreach (var userLog in invocationResult.Logs) { scriptInvocationContext.Logger?.LogInformation(userLog); } }, null); } }