Skip to content

[Enhanced Http] Support for http proxying scenarios #9193

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

Merged
merged 24 commits into from
Apr 4, 2023
Merged

Conversation

satvu
Copy link
Member

@satvu satvu commented Mar 31, 2023

Issue describing the changes in this PR

Add initial components for the enhanced HTTP model (read more here). These components are hidden behind a capability and this code path should only light up when a worker implementing the HTTP model provides the necessary info.

These are minimal changes needed to make it easier for partner teams and stakeholders to use and provide feedback as we continue to develop this feature.

Pull request checklist

  • My changes do not require documentation changes
    • Otherwise: Documentation issue linked to PR
  • My changes should not be added to the release notes for the next release
    • Otherwise: I've added my notes to release_notes.md
  • My changes do not need to be backported to a previous version
    • Otherwise: Backport tracked by issue/PR #issue_or_pr
  • My changes do not require diagnostic events changes
    • Otherwise: I have added/updated all related diagnostic events and their documentation (Documentation issue linked to PR)
  • I have added all required tests (Unit tests, E2E tests)

Additional information

Additional PR information

@satvu satvu marked this pull request as ready for review March 31, 2023 20:37
@satvu satvu requested a review from a team as a code owner March 31, 2023 20:37
@satvu satvu requested review from fabiocav and brettsam March 31, 2023 20:38
@satvu
Copy link
Member Author

satvu commented Mar 31, 2023

Working on tests but the rest is ready for review.

@satvu satvu requested a review from mathewc as a code owner April 3, 2023 17:28
@@ -2190,11 +2190,11 @@
"System.Runtime": "4.3.1"
}
},
"System.IO.Hashing/6.0.0": {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious why this file is included at all in our code base? Being a build/restore artifact, shouldn't it be excluded?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skipped this comment earlier but I am only editing it as it's needed to pass tests - it's a file in the test repo to make sure all dependency changes are caught and approval is asked from specific code owners (the test error message says so, you can see in earlier pipeline failures).

@@ -81,6 +82,9 @@ internal class GrpcWorkerChannel : IRpcWorkerChannel, IDisposable
private bool _isSharedMemoryDataTransferEnabled;
private bool? _cancelCapabilityEnabled;
private bool _isWorkerApplicationInsightsLoggingEnabled;
private IHttpProxyService _httpProxyService;
private Uri _httpProxyEndpoint;
private bool _isHttpProxyingWorker = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be cached when the worker is running under placeholder mode. Likely may not matter for dotnet worker. However, if there is customer config that controls the behavior then we may run into caching issues.

@@ -420,6 +426,21 @@ internal void WorkerInitResponse(GrpcEvent initEvent)
_isWorkerApplicationInsightsLoggingEnabled = true;
}

// If http proxying is enabled, we need to get the proxying endpoint of this worker
var httpUri = _workerCapabilities.GetCapabilityState(RpcWorkerConstants.HttpUri);
if (!string.IsNullOrEmpty(httpUri) && FeatureFlags.IsEnabled(ScriptConstants.FeatureFlagEnableHttpProxying))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FeatureFlags.IsEnabled(ScriptConstants.FeatureFlagEnableHttpProxying) will always be false for worker started in placeholder mode

@@ -738,6 +759,13 @@ internal async Task SendInvocationRequest(ScriptInvocationContext context)
{
context.CancellationToken.Register(() => SendInvocationCancel(invocationRequest.InvocationId));
}

if (_isHttpProxyingWorker && context.FunctionMetadata.IsHttpTriggerFunction())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IsHttpTriggerFunction explicitly looks at httpTrigger functions only. This does not include any webhooks from extensions such as durable or trigger that use http such as eventGrid. I am assuming this is by design.

@@ -16,6 +16,9 @@ public static IServiceCollection AddScriptGrpc(this IServiceCollection services)

services.AddSingleton<IRpcServer, AspNetCoreGrpcServer>();

services.AddHttpForwarder();
services.AddSingleton<IHttpProxyService, DefaultHttpProxyService>();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, we can't get this behind the feature flag (can't access FeatureFlags yet at this point, host will crash) so these services will be added but not used.

@@ -902,6 +930,17 @@ internal async Task InvokeResponse(InvocationResponse invokeResponse)
{
if (invokeResponse.Result.IsInvocationSuccess(context.ResultSource, capabilityEnabled))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if IsInvocationSuccess is false but the proxy request made it through. Also what happens when IsInvocationSuccess is false and proxy request has failed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The design for these cases hasn't been discussed but for now if IsInvocationSuccess fails at all we will ignore any proxying results and log an error.


if (_isHttpProxyingWorker && context.FunctionMetadata.IsHttpTriggerFunction())
{
var aspNetTask = _httpProxyService.Forward(context, _httpProxyEndpoint);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there any down sides of awaiting the task here? From what i am understanding the proxy request is already made here and awaiting the task simply provides with the forward errors if any. we can store the proxy result in the context and log it along with invocation success of failure.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Original design awaited the task here - I believe it changed because this task often completes after function invocation due to logic on the worker side (if there are no errors, this awaits until the http response is written back) and we decided to just send it off and unify if the function invocation succeeds.

{
public interface IHttpProxyService
{
public ValueTask<ForwarderError> Forward(ScriptInvocationContext context, Uri httpUri);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
public ValueTask<ForwarderError> Forward(ScriptInvocationContext context, Uri httpUri);
public ValueTask<ForwarderError> ForwardAsync(ScriptInvocationContext context, Uri httpUri);

Also, should this take in a CancellationToken? Or is one available on the context object?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jviau Yes CancellationToken implementation is something on the to-do list across the entire flow between host and worker.

@satvu
Copy link
Member Author

satvu commented Apr 4, 2023

Closing and postponing to next deadline instead.

@satvu satvu closed this Apr 4, 2023
@satvu satvu reopened this Apr 4, 2023
@satvu
Copy link
Member Author

satvu commented Apr 4, 2023

Noting again for the record this is for private preview and reopening again because we want to reemphasize the main concerns:

  • are we concerned about reliability?
  • are we concerned about our ability to iterate

If both are no, then this work should be fine for now. We want to put this in the hands of some PMs and ASP.NET partners for further validation.

@jviau
Copy link
Contributor

jviau commented Apr 4, 2023

So long as it is clear this is private preview and we are okay with making breaking changes later I am fine with this.

@satvu satvu merged commit 5c6c379 into dev Apr 4, 2023
@satvu satvu deleted the feature/enhanced-http branch April 4, 2023 20:08
@satvu satvu restored the feature/enhanced-http branch April 11, 2023 20:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants