Azure / azure-functions-dotnet-worker

Azure Functions out-of-process .NET language worker
MIT License
428 stars 182 forks source link

[Feedback] Custom trigger and isolated worker mode #1177

Open Greybird opened 1 year ago

Greybird commented 1 year ago

Hi,

Following .NET 7 release, which included removal of support for in-process function execution model, I'd like to share how I tried to adhere to the isolated worker approach for my custom trigger, and issues we are facing.

I'm doing it in Issues as Dicussions space is not open.

Context

MassTransit

In my company, we are heavy users of the MassTransit (doc site) library. We have plenty of procedures and ways of doing that are linked to how MassTransit is behaving.

One of them is the automatic topics, subscriptions, and queues creation at runtime, from message types, based on conventions (yes, it required credentials allowed to do so). Others include

image

Custom trigger

We previously used WebJobs a lot to consume messages, but we decided to move to functions.

To that end, we created a custom trigger that would allow us to get all the benefits from MassTransit library with the functions runtime.

You can find a very initial version here, that we published as part of a blob post, which should be simple enough to understand how it works.

If you take a look at the README, you will see that we relied on dependency injection to inject code configuration for the MassTransit library.

The result is quite crude, but works perfectly.

Issues encountered migrating to Isolated Worker

ExtensionInformation relying on nuget

The fact that the ExtensionInformationAttribute is relying on a nuget package is painful during development, and requires specific setup to be able to debug something. This is not a big issue, but it does not help

Ability to inject into the host

As the plugin relies on code to configure the trigger, we had to find a way to inject code into the host. The best solution we could find was to code an extension, as the extension would be executed in the host. As the configuration code relies on message types, we had to ensure the message types would be in a dedicated project too (not a big issue in our case, it was already the case to distribute them to clients through a specific nuget). Of course, for the trigger users, it would be more painful, as they would have to package a project as an extension, but at least it would work.

We did not find how to inject into the build process to register an extension, but it seems hard to do. So instead, we relied on manual modifications of extensions.json, and manual copy of files into the .azurefunctions. We had to add a few System.* dll for .NET 7, but this is probably to be expected as we hacked the build process.

So possible, but hard to find how to automate the extension registration in a simple way.

Unavailability of the parameter type on the trigger extension.

As said above, MassTransit uses conventions based on message types to configure the infrastructure. Even having the configuration extension running in the host, we discovered that the GRPC protocol did not transfer the attributed parameter type from the worker to the host, presenting it as a simple string, while the trigger expects it to be set to a proper parameter type.

As such, even relying on previous hacks, this made clear we would not be able to implement the customer trigger we wanted.

Conclusion

Could you clarify exactly where you are headed towards feature parity for custom triggers, and maybe a little bit of a timeframe for this parity to occur ?

The removal of the in-process model broke our ability to rely on functions, with little alternatives left currently, in a (probably small with regards to the functions world, but still) range of use cases.

Could we expect being able to inject configuration into the host easily ? And to have access to (nearly) the same information from an isolated worker than from an in-process work.

Thanks for reading !

SeanFeldman commented 1 year ago

Following .NET 7 release, which included removal of support for in-process function execution model, I'd like to share how I tried to adhere to the isolated worker approach for my custom trigger, and issues we are facing.

Unfortunately, that post hasn't aged well. There was an update, which should have been more prominent and amplified, which stated:

The previous post implied a specific timeline for phasing out the in-process model, with .NET 8 only supported on the isolated process model, which is possible but not guaranteed. That change would only occur if the isolated process has reached sufficient parity with the in-process model as outlined in this post. If it does not, there would be an in-process version of .NET 8 support.

With .NET 7 out, rephrased version would be "In-Process is not dead and continues till .NET 8 or feature parity, whichever comes first".

Greybird commented 1 year ago

Hi @SeanFeldman,

Thanks for your answer. It gives very interesting information, but I struggle to bring the pieces together.

When I use the Azure Functions project creation assistant in VS, I get no options for In-Process model for .NET 7: image

I also tried updating a .NET 6 functions project to net7.0, and uptating all dependencies, and ended up with errors at start, mostly pointing missing .NET 7 System assemblies

Could not load file or assembly 'System.ComponentModel, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.
Value cannot be null. (Parameter 'provider')

So should I understand what you are saying as ".NET 7.0 In-Process model is not available yet, but will be at some point"? It would reconcile both what I see from my tests and the blog post, and explain why there were communications (1 / 2) about the Isolated Worker model being available on .NET 7, but not mentioning the In-Process one.

Note that the 2nd one seem to imply that you must switch to Isolated Worker to benefit from .NET 7, which would contradict this position ?

.NET 7 in Azure Functions is supported by leveraging the .NET Isolated Worker process.

Sorry to ask for this, but could you confirm (or infirm and clarify) my understanding ?

SeanFeldman commented 1 year ago

@Greybird, I suspect the tooling is lagging behind. I'll let @satvu elaborate (she's from the team).

lgmorand commented 1 year ago

From the documentation, .Net 7 is not supported for in-process functions so it may not be just an issue of "tooling" behind because I would expect a "preview" or something. I didn't find anything telling that in-process would "disappear" with .Net 7.0 either, just announcements of the new isolated process.

@satvu would love any feedback from the PG please :) Are we missing something ? Is in-process planned ?

SeanFeldman commented 1 year ago

With .NET 7 not being an LTS, I see how the decision could have been to skip the investment and focus on bringing parity as a priority work for .NET 8 (LTS). That's what I think the diagram in the update post is depicting.

image

mattchenderson commented 1 year ago

Just jumping in to confirm that Sean's interpretation is correct. .NET 7 is intentionally only supported in the isolated process model. There are notable differences between those models, and we are working on bringing them into alignment. This report may be highlighting some additional differences needing discussion - thanks very much for filing it! I need to discuss some of the details with the team, but my initial first impression is that:

Again, those are just initial impressions from a first read-through. I'll discuss with @fabiocav.

Greybird commented 1 year ago

Thanks for this first feedbacks, I really appreciate the time and effort put into them, and am looking forward to receiving more information on the matter.

On a side note, I am under the impression that a new communication about the direction taken, and the current limitations and ongoing actions and their progress could be interesting for the community. Information seems to be available, but subject to interpretation/fine lines reading skills 😉, or scattered through various documents (blog posts, documentation, github, at least). Of course I am well aware that the models difference probably impact relatively few users and use cases. However, having clear expectations and timings in mind should help people / structures who invested in these specific usages better assess how to manage the situation.

lgmorand commented 1 year ago

Hi @mattchenderson

Any feedback after discussing with Fabio ? :)

lgmorand commented 1 year ago

@mattchenderson one last question please

if parity is not reached with .Net 8, can we expect in-process to come back with .Net 8 at the end of the year ?

liliankasem commented 1 year ago

@mattchenderson one last question please

if parity is not reached with .Net 8, can we expect in-process to come back with .Net 8 at the end of the year ?

We recently updated the roadmap: https://techcommunity.microsoft.com/t5/apps-on-azure-blog/net-on-azure-functions-august-2023-roadmap-update/ba-p/3910098

.NET 8 will be supported for in-proc

Greybird commented 1 year ago

.NET 8 will be supported for in-proc

Hi, thanks, that's a relief.

However, looking at the future, the parity of features as mentionned in the publication does not seem to mention the specific issues I mentionned in this thread (especially around configuration access and access to parameters type in the host). Can you confirm if the specific use case I reported in this thread will be covered by the parity definition? (because, we know, "parity" can mean different things to different people)

Thanks