-
Notifications
You must be signed in to change notification settings - Fork 201
Native host integration #1213
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Native host integration #1213
Changes from all commits
79ef17d
0acbbcf
38cc924
22d03a4
e8ed9da
c739811
34e06ec
c0cebf1
b157c61
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,10 +5,8 @@ | |
| using System.Linq; | ||
| using System.Runtime.InteropServices; | ||
| using System.Threading; | ||
| using System.Threading.Channels; | ||
| using System.Threading.Tasks; | ||
| using Azure.Core.Serialization; | ||
| using Grpc.Core; | ||
| using Microsoft.Azure.Functions.Worker.Context.Features; | ||
| using Microsoft.Azure.Functions.Worker.Core.FunctionMetadata; | ||
| using Microsoft.Azure.Functions.Worker.Grpc; | ||
|
|
@@ -21,52 +19,43 @@ | |
| using Microsoft.Extensions.Hosting; | ||
| using Microsoft.Extensions.Logging; | ||
| using Microsoft.Extensions.Options; | ||
| using static Microsoft.Azure.Functions.Worker.Grpc.Messages.FunctionRpc; | ||
| using MsgType = Microsoft.Azure.Functions.Worker.Grpc.Messages.StreamingMessage.ContentOneofCase; | ||
|
|
||
| namespace Microsoft.Azure.Functions.Worker | ||
| { | ||
| internal class GrpcWorker : IWorker | ||
| internal class GrpcWorker : IWorker, IMessageProcessor | ||
| { | ||
| private readonly ChannelReader<StreamingMessage> _outputReader; | ||
| private readonly ChannelWriter<StreamingMessage> _outputWriter; | ||
|
|
||
| private readonly IFunctionsApplication _application; | ||
| private readonly FunctionRpcClient _rpcClient; | ||
| private readonly IInvocationFeaturesFactory _invocationFeaturesFactory; | ||
| private readonly IOutputBindingsInfoProvider _outputBindingsInfoProvider; | ||
| private readonly IInputConversionFeatureProvider _inputConversionFeatureProvider; | ||
| private readonly IMethodInfoLocator _methodInfoLocator; | ||
| private readonly GrpcWorkerStartupOptions _startupOptions; | ||
| private readonly WorkerOptions _workerOptions; | ||
| private readonly ObjectSerializer _serializer; | ||
| private readonly IHostApplicationLifetime _hostApplicationLifetime; | ||
| private readonly IWorkerClientFactory _workerClientFactory; | ||
| private readonly IInvocationHandler _invocationHandler; | ||
| private readonly IFunctionMetadataProvider _functionMetadataProvider; | ||
|
|
||
| public GrpcWorker(IFunctionsApplication application, FunctionRpcClient rpcClient, GrpcHostChannel outputChannel, IInvocationFeaturesFactory invocationFeaturesFactory, | ||
| IOutputBindingsInfoProvider outputBindingsInfoProvider, IMethodInfoLocator methodInfoLocator, | ||
| IOptions<GrpcWorkerStartupOptions> startupOptions, IOptions<WorkerOptions> workerOptions, | ||
| IInputConversionFeatureProvider inputConversionFeatureProvider, | ||
| IFunctionMetadataProvider functionMetadataProvider, | ||
| IHostApplicationLifetime hostApplicationLifetime, | ||
| ILogger<GrpcWorker> logger) | ||
| private IWorkerClient? _workerClient; | ||
|
|
||
| public GrpcWorker(IFunctionsApplication application, | ||
| IWorkerClientFactory workerClientFactory, | ||
| IInvocationFeaturesFactory invocationFeaturesFactory, | ||
| IOutputBindingsInfoProvider outputBindingsInfoProvider, | ||
| IMethodInfoLocator methodInfoLocator, | ||
| IOptions<WorkerOptions> workerOptions, | ||
| IInputConversionFeatureProvider inputConversionFeatureProvider, | ||
| IFunctionMetadataProvider functionMetadataProvider, | ||
| IHostApplicationLifetime hostApplicationLifetime, | ||
| ILogger<GrpcWorker> logger) | ||
| { | ||
| if (outputChannel == null) | ||
| { | ||
| throw new ArgumentNullException(nameof(outputChannel)); | ||
| } | ||
|
|
||
| _outputReader = outputChannel.Channel.Reader; | ||
| _outputWriter = outputChannel.Channel.Writer; | ||
|
|
||
| _hostApplicationLifetime = hostApplicationLifetime ?? throw new ArgumentNullException(nameof(hostApplicationLifetime)); | ||
| _workerClientFactory = workerClientFactory ?? throw new ArgumentNullException(nameof(workerClientFactory)); | ||
| _application = application ?? throw new ArgumentNullException(nameof(application)); | ||
| _rpcClient = rpcClient ?? throw new ArgumentNullException(nameof(rpcClient)); | ||
| _invocationFeaturesFactory = invocationFeaturesFactory ?? throw new ArgumentNullException(nameof(invocationFeaturesFactory)); | ||
| _outputBindingsInfoProvider = outputBindingsInfoProvider ?? throw new ArgumentNullException(nameof(outputBindingsInfoProvider)); | ||
| _methodInfoLocator = methodInfoLocator ?? throw new ArgumentNullException(nameof(methodInfoLocator)); | ||
| _startupOptions = startupOptions?.Value ?? throw new ArgumentNullException(nameof(startupOptions)); | ||
|
|
||
| _workerOptions = workerOptions?.Value ?? throw new ArgumentNullException(nameof(workerOptions)); | ||
| _serializer = workerOptions.Value.Serializer ?? throw new InvalidOperationException(nameof(workerOptions.Value.Serializer)); | ||
| _inputConversionFeatureProvider = inputConversionFeatureProvider ?? throw new ArgumentNullException(nameof(inputConversionFeatureProvider)); | ||
|
|
@@ -78,54 +67,16 @@ public GrpcWorker(IFunctionsApplication application, FunctionRpcClient rpcClient | |
|
|
||
| public async Task StartAsync(CancellationToken token) | ||
| { | ||
| var eventStream = _rpcClient.EventStream(cancellationToken: token); | ||
|
|
||
| await SendStartStreamMessageAsync(eventStream.RequestStream); | ||
|
|
||
| _ = StartWriterAsync(eventStream.RequestStream); | ||
| _ = StartReaderAsync(eventStream.ResponseStream); | ||
| _workerClient = await _workerClientFactory.StartClientAsync(this, token); | ||
| } | ||
|
|
||
| public Task StopAsync(CancellationToken token) | ||
| { | ||
| return Task.CompletedTask; | ||
| } | ||
| public Task StopAsync(CancellationToken token) => Task.CompletedTask; | ||
|
|
||
| private async Task SendStartStreamMessageAsync(IClientStreamWriter<StreamingMessage> requestStream) | ||
| { | ||
| StartStream str = new StartStream() | ||
| { | ||
| WorkerId = _startupOptions.WorkerId | ||
| }; | ||
|
|
||
| StreamingMessage startStream = new StreamingMessage() | ||
| { | ||
| StartStream = str | ||
| }; | ||
|
|
||
| await requestStream.WriteAsync(startStream); | ||
| } | ||
|
|
||
| private async Task StartWriterAsync(IClientStreamWriter<StreamingMessage> requestStream) | ||
| { | ||
| await foreach (StreamingMessage rpcWriteMsg in _outputReader.ReadAllAsync()) | ||
| { | ||
| await requestStream.WriteAsync(rpcWriteMsg); | ||
| } | ||
| } | ||
|
|
||
| private async Task StartReaderAsync(IAsyncStreamReader<StreamingMessage> responseStream) | ||
| { | ||
| while (await responseStream.MoveNext()) | ||
| { | ||
| await ProcessRequestAsync(responseStream.Current); | ||
| } | ||
| } | ||
|
|
||
| private Task ProcessRequestAsync(StreamingMessage request) | ||
| Task IMessageProcessor.ProcessMessageAsync(StreamingMessage message) | ||
| { | ||
| // Dispatch and return. | ||
| Task.Run(() => ProcessRequestCoreAsync(request)); | ||
| _ = ProcessRequestCoreAsync(message); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should also update env reload case (line 116) to return capabilities and worker metadata. Can be a follow up PR I can take care of.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Has the host been updated to support that? yes, we should, but either way, I'm inclined to say this should be a separate change |
||
|
|
||
| return Task.CompletedTask; | ||
| } | ||
|
|
||
|
|
@@ -179,7 +130,7 @@ private async Task ProcessRequestCoreAsync(StreamingMessage request) | |
| return; | ||
| } | ||
|
|
||
| await _outputWriter.WriteAsync(responseMessage); | ||
| await _workerClient!.SendMessageAsync(responseMessage); | ||
| } | ||
|
|
||
| internal Task<InvocationResponse> InvocationRequestHandlerAsync(InvocationRequest request) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.