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

Feature request: Support Native AOT #212

Open
1 of 2 tasks
hjgraca opened this issue Feb 17, 2023 · 11 comments
Open
1 of 2 tasks

Feature request: Support Native AOT #212

hjgraca opened this issue Feb 17, 2023 · 11 comments
Labels
aot feature-request New or enhancements to existing features pending-release Fix or implementation already in dev waiting to be released
Milestone

Comments

@hjgraca
Copy link
Contributor

hjgraca commented Feb 17, 2023

Use case

Historically, .NET Lambda functions have cold-start times which impact user experience, system latency, and usage costs of your serverless applications. With .NET 8, Microsoft adds support for Native AOT compilation, which speeds up performance by compiling .NET code directly to machine and operating system native code, eliminating Just-in-Time (JIT) compiling at runtime. With .NET 8 Native AOT compilation, you can improve cold-start times of your Lambda functions. To learn more about Native AOT for .NET 8, see Using Native AOT in the Dotnet GitHub repository.

Solution/User Experience

Currently Native AOT is supported in .NET 8 but only a limited number of libraries are fully compatible with native AOT in .NET 8.
Lambda Powertools is not fully compatible with native AOT because of some libraries it uses (for example System.Text.Json.Serializer) which is not supported in native AOT

Proposal

All the work for this release will happen in a separate branch aot-support, this will allow us to publish alpha releases to Nuget. This will allow customers to get early access to the new features and optionally start applying the required changes or simply give feedback on the new items.

Quick summary

The work for AOT support will be done in multiple phases beginning on supporting Logging and Metrics and continuing to the remaining utilities. We believe these two utilities will have the most work and that is the reason we are starting from there.

Item Issue Status Code change required Notes
.NET 8 support #542
Create automation for .NET 8 release multiple target frameworks #542
Logging AOT support #628 Yes
Logging tackle AOT warnings #628 100+ warnings
Metrics AOT support #602 Yes
Metrics tackle AOT warnings #602 Yes 10+ warnings
Tracing AOT support #607 Yes
Tracing tackle AOT warnings #607 Yes 10+ warnings
Create guide in docs 🗓
Idempotency AOT support 🗓️ Yes
Idempotency tackle AOT warnings Yes 10+ warnings
Batch AOT support 🗓️ Yes
Batch tackle AOT warnings Yes 10+ warnings
Parameters AOT support 🗓️ Yes
Parameters tackle AOT warnings Yes 10+ warnings

Legend for Status column:

  • ✅ Completed
  • 🚧 Work in Progress
  • ❌ Canceled / rescheduled to future release
  • 🗓Backlog

Potential challenges

Tackling AOT trim warnings will be the most time consuming tasks, for this reason if some unforeseen blocker comes up we might decide to reprioritize and exclude some issues from the milestone.

Acknowledgment

@hjgraca hjgraca added feature-request New or enhancements to existing features triage Pending triage from maintainers labels Feb 17, 2023
@hjgraca hjgraca moved this to 👀 In review in AWS Lambda Powertools for .NET Mar 2, 2023
@hjgraca hjgraca moved this from 👀 In review to Ideas in AWS Lambda Powertools for .NET Mar 2, 2023
@hjgraca hjgraca added the aot label Mar 2, 2023
@hjgraca hjgraca changed the title Feature request: Support .NET 7 Native AOT Feature request: Support Native AOT Jun 7, 2023
@hjgraca hjgraca removed the triage Pending triage from maintainers label Jun 21, 2023
@jeastham1993
Copy link

@hjgraca PR raised for the first pass on native AOT support. I expect this will need some discussion, especially around logging. We can't easily support Exceptions in their entirety, byte[], streams or any anoymous types. Some of the unit tests will fail based on this missing functionality but I thought I would leave it that way as a means of discussion

#341

The crux of the work is adding a new IPowerToolsSerializer, initially with 2 implementations. A default one that uses System.Text.Json, and then a source genereted one that allows users to add a custom serialization context.

This is the same way it works for the Lambda runtime itself.

@hjgraca hjgraca linked a pull request Jul 6, 2023 that will close this issue
7 tasks
@hjgraca hjgraca moved this from Ideas to 🏗 In progress in Powertools for AWS Lambda (.NET) Jul 6, 2023
@github-actions github-actions bot added the pending-release Fix or implementation already in dev waiting to be released label Jan 24, 2024
@hjgraca
Copy link
Contributor Author

hjgraca commented Feb 21, 2024

We have released alpha versions for Logging and Metrics. They are now available to download from Nuget.

These are very early release versions and not recommended for production workloads, we have done our best to support all features, but you will see some warnings when trimming for AOT deployment.

@hjgraca hjgraca removed the pending-release Fix or implementation already in dev waiting to be released label Feb 21, 2024
@github-actions github-actions bot added the pending-release Fix or implementation already in dev waiting to be released label Mar 15, 2024
@andy-potter-evotix
Copy link

We are using .NET8 AOT based lambda in development at the moment with the 1.6.0-alpha version of the PowerTools logging. We are due to go to production in around 4-6 weeks time. Do you have plans to release a production ready version of PowerTools logging with AOT support?

@hjgraca
Copy link
Contributor Author

hjgraca commented Apr 26, 2024

Hi @andy-potter-evotix thanks for using Powertools, the full support of AOT is top priority and we are working as fast as we can to ship it as soon as possible, unfortunately I cannot guarantee delivery dates, but in the next weeks we will be releasing another alpha and more stable versions.
Hopefully we can get something by that time that we are confident that can go to production.
Keep an eye on this issue we will update whenever we have news.
If you want to reach us directly use can use the email [email protected]

Again thanks for using Powertools 👍

@hjgraca hjgraca pinned this issue Jul 9, 2024
@heitorlessa heitorlessa removed the pending-release Fix or implementation already in dev waiting to be released label Jul 25, 2024
@hjgraca hjgraca mentioned this issue Aug 2, 2024
7 tasks
@github-actions github-actions bot added the pending-release Fix or implementation already in dev waiting to be released label Sep 23, 2024
@Euclidite
Copy link

@hjgraca I wanted to confirm - Is the Logging/Metric support for trimming officially completed/supported? I'm having some issue getting it working on my end even with the recommended changes.

@hjgraca
Copy link
Contributor Author

hjgraca commented Oct 10, 2024

@Euclidite yes it is implemented in both Logging and Metrics, Logging > 1.6.0 and Metrics > 1.7.1.
What is the issue/erro you are seeing?

@Euclidite
Copy link

Euclidite commented Oct 10, 2024

Here's the exception I get in the logs (which is telling me "I didn't configure something right"):

10-Oct-2024 9:34:07 AM	2024-10-10T13:34:07.448Z 9bc362e6-76bc-4f22-b004-8c5622ca8078 fail System.InvalidOperationException: Reflection-based serialization has been disabled for this application. Either use the source generator APIs or explicitly configure the 'JsonSerializerOptions.TypeInfoResolver' property.
   at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_JsonSerializerIsReflectionDisabled()
   at System.Text.Json.JsonSerializerOptions.ConfigureForJsonSerializer()
   at System.Text.Json.JsonSerializer.GetTypeInfo(JsonSerializerOptions, Type)
   at System.Text.Json.JsonSerializer.GetTypeInfo[T](JsonSerializerOptions)
   at System.Text.Json.JsonSerializer.Serialize[TValue](TValue, JsonSerializerOptions )
   at AWS.Lambda.Powertools.Logging.Serializers.PowertoolsLoggingSerializer.Serialize(Object, Type)
   at AWS.Lambda.Powertools.Logging.Internal.PowertoolsLogger.Log[TState](LogLevel, EventId, TState, Exception, Func`3)
   at Microsoft.Extensions.Logging.LoggerExtensions.Log(ILogger , LogLevel, EventId, Exception, String, Object[] )
   at Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(ILogger, String , Object[] )
   at submit_feedback.Function.FunctionHandlerAsync(SubmitFeedbackRequest request, ILambdaContext context) in ./Function.cs:line 63
   at Amazon.Lambda.RuntimeSupport.HandlerWrapper.<>c__DisplayClass14_0`1.<<GetHandlerWrapper>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Amazon.Lambda.RuntimeSupport.LambdaBootstrap.InvokeOnceAsync(CancellationToken )

Here are the relevant lines of what I have in my csproj file (Let me know if you need more context):

<PropertyGroup>
    <PublishReadyToRun>true</PublishReadyToRun>
    <StripSymbols>true</StripSymbols>
    <PublishTrimmed>true</PublishTrimmed>
    <TrimMode>partial</TrimMode>
</PropertyGroup>
<ItemGroup>
    <!-- Exclude EF Core assemblies from being trimmed (not supported) -->
    <TrimmerRootAssembly Include="Microsoft.EntityFrameworkCore" />
    <TrimmerRootAssembly Include="Microsoft.EntityFrameworkCore.Relational" />
    <TrimmerRootAssembly Include="Npgsql.EntityFrameworkCore.PostgreSQL" />
    <TrimmerRootAssembly Include="EFCore.NamingConventions" />
</ItemGroup>

And here's how I've been able to minimally reproduce this:

public class Function
{
    private static async Task Main()
    {
        await LambdaBootstrapBuilder.Create<SubmitFeedbackRequest>(
                                        FunctionHandlerAsync,
                                        new PowertoolsSourceGeneratorSerializer<LambdaFunctionJsonContext>())
            .Build()
            .RunAsync();
    }

   [Logging]
   public static async Task FunctionHandlerAsync(SubmitFeedbackRequest request, ILambdaContext context)
   {
       Logger.LogInformation("Starting up!");
    }
}

[JsonSerializable(typeof(SubmitFeedbackRequest))]
public partial class LambdaFunctionJsonContext : JsonSerializerContext { }

For reference, here are my package versions:
Image

@hjgraca
Copy link
Contributor Author

hjgraca commented Oct 10, 2024

Not sure if it makes a difference but I usually build the handler in the main like so.

 Func< SubmitFeedbackRequest, ILambdaContext, Task> handler = FunctionHandler;
        await LambdaBootstrapBuilder.Create(handler, new PowertoolsSourceGeneratorSerializer< LambdaFunctionJsonContext >())
            .Build()
            .RunAsync();

@Euclidite
Copy link

I've updated my main to this:

    private static async Task Main()
    {
        Console.WriteLine("Starting up");
        Func<SubmitFeedbackRequest, ILambdaContext, Task> handler = FunctionHandlerAsync;
        await LambdaBootstrapBuilder.Create(handler, new PowertoolsSourceGeneratorSerializer<LambdaFunctionJsonContext>())
            .Build()
            .RunAsync();

        Console.WriteLine("Shutting down");
    }

Unfortunately, I still get the same exception logged.

Let me know if you'd like a new ticket, or if you want to dig into it a bit first 🙂

@hjgraca
Copy link
Contributor Author

hjgraca commented Oct 10, 2024

Please open an issue, from my initial tests is because the Lambda is not returning any values.
Thank you!

@Euclidite
Copy link

Created #668!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
aot feature-request New or enhancements to existing features pending-release Fix or implementation already in dev waiting to be released
Projects
Status: 🏗 In progress
Development

Successfully merging a pull request may close this issue.

5 participants