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

Add trimming support for RuntimeSupport, SystemTextJson serializer and Lambda event packages #1596

Merged
merged 5 commits into from Oct 26, 2023

Conversation

normj
Copy link
Member

@normj normj commented Oct 25, 2023

Description of changes:
Updated the Lambda RuntimeSupport, SystemTextJson serializer and Lambda events to support trimming.

  • Replaced all NETCOREAPP_3_1 preprocessor references to NETCOREAPP3_1_OR_GREATER
  • Added net8.0 target framework to projects and mark the projects as trimmable.
  • Marked all serializer in the SystemTextJson as requiring unreferenced code except for the source generator seriralizer
  • There were a couple places where an event was directly using the SystemTextJson serializer. For .NET 8 I switched it to use the source generator approach.
  • In Amazon.Lambda.RuntimeSupport marked the code paths used by the class library approach of loading the customer function by reflection and build Expressions as RequiresUnreferencedCode. These code paths are not used when deployed as an executable which is the AOT use case.
  • Updated the Events.NET6 project to multi target .NET 8. At some point we should rename this project but I don't want to mess with the CI system right now.
  • Added a new constructor for SourceGeneratorLambdaJsonSerializer that takes in the JsonSerializerContext so the serializer doesn't have to use reflection to get an instance of the generic parameter.

I have verified with these changes I can package a Lambda function using just these libraries and received no trim warnings.

Work not included in this PR

  • Update the ASP.NET Core bridge to support trimming
  • Update Lambda Annotations to support .NET 8 and trimming

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

{
if (value is System.Enum)
Copy link
Member Author

Choose a reason for hiding this comment

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

This code was not trimming compatible and it turn out our only use of the method was to the value being a string. So I choose to just simplify this method. Along time again this class was generated from a swagger file which I assume the generator just differentiated for all possible use cases.

Label = method.Name;
}
else
var method = stackFrame.GetMethod();
Copy link
Member Author

Choose a reason for hiding this comment

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

This GetMethod call is marked as RequiresUnreferencedCode. The code is required so I just made the code more defensive in case something gets trimmed. Since we only really need the that is unlikely to be metadata trimmed.

Copy link
Member

@ashovlin ashovlin left a comment

Choose a reason for hiding this comment

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

And for the failed CI, can you add a .NET 8 block here?

- name: Setup .NET 3.1
uses: actions/setup-dotnet@v1
with:
dotnet-version: 3.1.x
- name: Setup .NET 6.0
uses: actions/setup-dotnet@v1
with:
dotnet-version: 6.0.x

@@ -47,8 +47,12 @@ public class DictionaryLongToStringJsonConverter : JsonConverter<Dictionary<stri

public override void Write(Utf8JsonWriter writer, Dictionary<string, string> value, JsonSerializerOptions options)
{
#if NET8_0_OR_GREATER
JsonSerializer.Serialize(writer, value, typeof(Dictionary<string, string>), new DictionaryStringStringJsonSerializerContext(options));
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be helpful to add a comment here explaining why we're doing it this way for .NET8 and above

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

@@ -47,8 +47,12 @@ public class DictionaryLongToStringJsonConverter : JsonConverter<Dictionary<stri

public override void Write(Utf8JsonWriter writer, Dictionary<string, string> value, JsonSerializerOptions options)
{
#if NET8_0_OR_GREATER
JsonSerializer.Serialize(writer, value, typeof(Dictionary<string, string>), new DictionaryStringStringJsonSerializerContext(options));
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be helpful to add a comment here explaining why we're doing it this way for .NET8 and above

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

<PropertyGroup Condition="'$(TargetFramework)' == 'net8.0'">
<WarningsAsErrors>IL2026,IL2067,IL2075</WarningsAsErrors>
<IsTrimmable>true</IsTrimmable>
<EnableTrimAnalyzer>true</EnableTrimAnalyzer>
Copy link
Contributor

Choose a reason for hiding this comment

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

Why does RuntimeSupport need EnableTrimAnalyzer but the rest don't?

Copy link
Member Author

Choose a reason for hiding this comment

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

Added EnableTrimAnalyzer to the other projects. I added this property so we can see future breaks to trimming at compile time for these libraries.

@@ -112,6 +112,11 @@ private LambdaBootstrap(HttpClient httpClient, LambdaBootstrapHandler handler, L
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns>A Task that represents the operation.</returns>
#if NET8_0_OR_GREATER
[System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026",
Justification = "Unreferenced code paths are excluding when RuntimeFeature.IsDynamicCodeSupported is false.")]
Copy link
Contributor

Choose a reason for hiding this comment

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

"excluding" should 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.

Fixed

@@ -41,10 +41,14 @@ public override bool CanConvert(Type typeToConvert)
/// <param name="typeToConvert"></param>
/// <param name="options"></param>
/// <returns></returns>
#if NET8_0_OR_GREATER
[System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("ReflectionAnalysis", "IL2067",
Justification = "Constant classes are only used in the DynamoDB event referencing the SDK. S3 originally referenced the SDK but has been rewritten to no longer reference the SDK or ConstantClass. Suppressing this trim warning because we have marked the DynamoDB event as ")]
Copy link
Contributor

Choose a reason for hiding this comment

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

sentence incomplete? what did we mark the DynamoDB event as?

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed

Copy link
Contributor

@philasmar philasmar left a comment

Choose a reason for hiding this comment

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

Approved, assuming you fix the failing PR checks

@normj
Copy link
Member Author

normj commented Oct 26, 2023

And for the failed CI, can you add a .NET 8 block here?

- name: Setup .NET 3.1
uses: actions/setup-dotnet@v1
with:
dotnet-version: 3.1.x
- name: Setup .NET 6.0
uses: actions/setup-dotnet@v1
with:
dotnet-version: 6.0.x

Fixed the CI build. Since .NET 8 isn't GA I had to set the workflow to the current RC. Will need to update that to 8.0.x once .NET 8 has been released.

@normj normj changed the base branch from master to dev October 26, 2023 16:47
@normj normj merged commit 0022859 into dev Oct 26, 2023
3 checks passed
@normj normj deleted the normj/add-trimming-support branch October 26, 2023 16:47
@@ -140,6 +140,9 @@ public static void LoadStringCultureInfo()
}
}

#if NET8_0_OR_GREATER
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("PreJitAssembly is not used for Native AOT")]
Copy link
Contributor

Choose a reason for hiding this comment

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

Technically someone could want to trim their assembly and not use native AOT, although obviously native AOT is the big use case. In general some of the explanations assume trimming = native AOT, and it might help to be a little more clear why that is going forward.

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.

None yet

4 participants