Skip to content
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

Improved middleware support to enable Durable Functions #739

Closed
cgillum opened this issue Dec 2, 2021 · 6 comments
Closed

Improved middleware support to enable Durable Functions #739

cgillum opened this issue Dec 2, 2021 · 6 comments
Assignees
Labels
extensions: durable-functions Items related to Durable Functions support needs-discussion

Comments

@cgillum
Copy link
Member

cgillum commented Dec 2, 2021

Orchestrator functions in Durable Functions have some very special requirements in terms of how they deal with inputs, outputs, and invocation. In WebJobs, we were able to take advantage of abstractions like invocation handlers to inject trigger-specific middleware into the orchestrator function execution pipeline. This was needed so that we could wrap the function execution in the body of a Durable Task Framework orchestration, manipulate the function inputs and outputs, and short-circuit the function execution when an await is encountered for the first time. However, there are some issues with the .NET worker extensibility that make it hard for us to implement this same functionality for .NET Isolated.

I looked at IFunctionsWorkerMiddleware, which seems to be the closest thing to invocation handlers, but there seem to be a few issues with it:

  • According to this issue (caveat: not sure if it reflects the current reality), middleware doesn't support changing the input or output of a function. I haven't yet looked to see whether IInputConverter can be combined with IFunctionsWorkerMiddleware.
  • Middleware must be injected into the host by the developer. It's not practical for Durable Functions scenarios to require developers to add middleware themselves. It would be much preferred that it can be injected automatically whenever someone adds an [OrchestrationTrigger] function to their code (similar to InputConverterAttribute, which we can place on our predefined input types).
  • All middlewares are global. Function or trigger-specific middleware is preferred.

The issues above are ordered by perceived severity.

@cgillum cgillum added the extensions: durable-functions Items related to Durable Functions support label Dec 2, 2021
@ghost ghost assigned kshyju Dec 2, 2021
@anthonychu
Copy link
Member

@cgillum Let's set up something in the new year to discuss this and update this thread.

@julealgon
Copy link

@cgillum Let's set up something in the new year to discuss this and update this thread.

Any updates you guys could share?

@cgillum
Copy link
Member Author

cgillum commented Feb 24, 2022

I believe it's being worked on as we speak, and I'm waiting eagerly to try it out. :) (speaking about the middleware part)

@kshyju
Copy link
Member

kshyju commented Mar 8, 2022

Yes, the second item is in-progress. #798 tracks the progress of that work.

@kshyju
Copy link
Member

kshyju commented May 5, 2022

Version 1.8.0-preview1 of Microsoft.Azure.Functions.Worker package introduces a few new APIs which addresses the 3 items mentioned.

  1. To update input binding data, output binding data and invocation result, use any of the below extension methods on FunctionContext.
public static ValueTask<InputBindingData<T>> BindInputAsync<T>(BindingMetadata bindingMetadata);
public static InvocationResult<T> GetInvocationResult<T>();;
public static InvocationResult GetInvocationResult();
public static IEnumerable<OutputBindingData<T>> GetOutputBindings<T>();

// Http trigger specific
public static ValueTask<HttpRequestData?> GetHttpRequestDataAsync();
public static HttpResponseData? GetHttpResponseData();

The sample project has some examples of this API usage.

  1. We also added the support for startup hooks. This allow extension authors to register extension specific startup code, which can include registering middleware relevant to the extension. See the PR description for example.
  2. The UseWhen extension method can be used to register a middleware which gets executed conditionally. Example usage here.

@kshyju kshyju closed this as completed May 5, 2022
@justinmchase
Copy link

Is it possible to update the input bindings themselves during the startup?

@ghost ghost locked as resolved and limited conversation to collaborators Jun 10, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
extensions: durable-functions Items related to Durable Functions support needs-discussion
Projects
None yet
Development

No branches or pull requests

5 participants