Skip to content

Commit e5f2c8f

Browse files
committed
Update the Minimal API extension method to use GetBeforeSnapshotRequests.
1 parent 71540b3 commit e5f2c8f

16 files changed

Lines changed: 233 additions & 466 deletions

.autover/changes/38c5bace-4ca5-4f83-8094-ae6d912ca20a.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"Name": "Amazon.Lambda.AspNetCoreServer.Hosting",
55
"Type": "Patch",
66
"ChangelogMessages": [
7-
"Add AddAWSLambdaBeforeSnapshotRequest to support warming up the asp.net/lambda pipelines automatically during BeforeSnapshot callback."
7+
"Add overrideable method GetBeforeSnapshotRequests() and AddAWSLambdaBeforeSnapshotRequest() extension method to support warming up the asp.net/lambda pipelines automatically during BeforeSnapshot callback."
88
]
99
}
1010
]

Libraries/src/Amazon.Lambda.AspNetCoreServer.Hosting/Amazon.Lambda.AspNetCoreServer.Hosting.csproj

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@
2727
<ProjectReference Include="..\Amazon.Lambda.APIGatewayEvents\Amazon.Lambda.APIGatewayEvents.csproj" />
2828
<ProjectReference Include="..\Amazon.Lambda.AspNetCoreServer\Amazon.Lambda.AspNetCoreServer.csproj" />
2929
<ProjectReference Include="..\Amazon.Lambda.RuntimeSupport\Amazon.Lambda.RuntimeSupport.csproj" />
30-
<ProjectReference Include="..\Amazon.Lambda.Serialization.SystemTextJson\Amazon.Lambda.Serialization.SystemTextJson.csproj" />
31-
32-
</ItemGroup>
30+
</ItemGroup>
3331

3432
</Project>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
using Microsoft.Extensions.DependencyInjection;
5+
6+
namespace Amazon.Lambda.AspNetCoreServer.Hosting.Internal;
7+
8+
/// <summary>
9+
/// Helper class for storing Requests for
10+
/// <see cref="ServiceCollectionExtensions.AddAWSLambdaBeforeSnapshotRequest"/>
11+
/// </summary>
12+
internal class GetBeforeSnapshotRequestsCollector
13+
{
14+
public HttpRequestMessage? Requests { get; set; }
15+
}
16+

Libraries/src/Amazon.Lambda.AspNetCoreServer.Hosting/Internal/LambdaRuntimeSupportServer.cs

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,6 @@ public abstract class LambdaRuntimeSupportServer : LambdaServer
1717
{
1818
private readonly IServiceProvider _serviceProvider;
1919

20-
#if NET8_0_OR_GREATER
21-
private readonly LambdaSnapstartExecuteRequestsBeforeSnapshotHelper _snapstartInitHelper;
22-
#endif
23-
2420
internal ILambdaSerializer Serializer;
2521

2622
/// <summary>
@@ -31,10 +27,6 @@ public LambdaRuntimeSupportServer(IServiceProvider serviceProvider)
3127
{
3228
_serviceProvider = serviceProvider;
3329

34-
#if NET8_0_OR_GREATER
35-
_snapstartInitHelper = _serviceProvider.GetRequiredService<LambdaSnapstartExecuteRequestsBeforeSnapshotHelper>();
36-
#endif
37-
3830
Serializer = serviceProvider.GetRequiredService<ILambdaSerializer>();
3931
}
4032

@@ -51,12 +43,6 @@ public override Task StartAsync<TContext>(IHttpApplication<TContext> application
5143

5244
var handlerWrapper = CreateHandlerWrapper(_serviceProvider);
5345

54-
#if NET8_0_OR_GREATER
55-
56-
_snapstartInitHelper.RegisterInitializerRequests(handlerWrapper);
57-
58-
#endif
59-
6046
var bootStrap = new LambdaBootstrap(handlerWrapper);
6147
return bootStrap.RunAsync();
6248
}
@@ -99,14 +85,26 @@ protected override HandlerWrapper CreateHandlerWrapper(IServiceProvider serviceP
9985
/// </summary>
10086
public class APIGatewayHttpApiV2MinimalApi : APIGatewayHttpApiV2ProxyFunction
10187
{
88+
private readonly IEnumerable<GetBeforeSnapshotRequestsCollector> _beforeSnapshotRequestsCollectors;
89+
10290
/// <summary>
10391
/// Create instances
10492
/// </summary>
10593
/// <param name="serviceProvider">The IServiceProvider created for the ASP.NET Core application</param>
10694
public APIGatewayHttpApiV2MinimalApi(IServiceProvider serviceProvider)
10795
: base(serviceProvider)
10896
{
97+
_beforeSnapshotRequestsCollectors = serviceProvider.GetServices<GetBeforeSnapshotRequestsCollector>();
98+
}
99+
100+
#if NET8_0_OR_GREATER
101+
protected override IEnumerable<HttpRequestMessage> GetBeforeSnapshotRequests()
102+
{
103+
foreach (var collector in _beforeSnapshotRequestsCollectors)
104+
if (collector.Requests != null)
105+
yield return collector.Requests;
109106
}
107+
#endif
110108
}
111109
}
112110

@@ -140,14 +138,26 @@ protected override HandlerWrapper CreateHandlerWrapper(IServiceProvider serviceP
140138
/// </summary>
141139
public class APIGatewayRestApiMinimalApi : APIGatewayProxyFunction
142140
{
141+
private readonly IEnumerable<GetBeforeSnapshotRequestsCollector> _beforeSnapshotRequestsCollectors;
142+
143143
/// <summary>
144144
/// Create instances
145145
/// </summary>
146146
/// <param name="serviceProvider">The IServiceProvider created for the ASP.NET Core application</param>
147147
public APIGatewayRestApiMinimalApi(IServiceProvider serviceProvider)
148148
: base(serviceProvider)
149149
{
150+
_beforeSnapshotRequestsCollectors = serviceProvider.GetServices<GetBeforeSnapshotRequestsCollector>();
150151
}
152+
153+
#if NET8_0_OR_GREATER
154+
protected override IEnumerable<HttpRequestMessage> GetBeforeSnapshotRequests()
155+
{
156+
foreach (var collector in _beforeSnapshotRequestsCollectors)
157+
if (collector.Requests != null)
158+
yield return collector.Requests;
159+
}
160+
#endif
151161
}
152162
}
153163

@@ -181,14 +191,26 @@ protected override HandlerWrapper CreateHandlerWrapper(IServiceProvider serviceP
181191
/// </summary>
182192
public class ApplicationLoadBalancerMinimalApi : ApplicationLoadBalancerFunction
183193
{
194+
private readonly IEnumerable<GetBeforeSnapshotRequestsCollector> _beforeSnapshotRequestsCollectors;
195+
184196
/// <summary>
185197
/// Create instances
186198
/// </summary>
187199
/// <param name="serviceProvider">The IServiceProvider created for the ASP.NET Core application</param>
188200
public ApplicationLoadBalancerMinimalApi(IServiceProvider serviceProvider)
189201
: base(serviceProvider)
190202
{
203+
_beforeSnapshotRequestsCollectors = serviceProvider.GetServices<GetBeforeSnapshotRequestsCollector>();
204+
}
205+
206+
#if NET8_0_OR_GREATER
207+
protected override IEnumerable<HttpRequestMessage> GetBeforeSnapshotRequests()
208+
{
209+
foreach (var collector in _beforeSnapshotRequestsCollectors)
210+
if (collector.Requests != null)
211+
yield return collector.Requests;
191212
}
213+
#endif
192214
}
193215
}
194216
}

Libraries/src/Amazon.Lambda.AspNetCoreServer.Hosting/Internal/LambdaSnapstartExecuteRequestsBeforeSnapshotHelper.cs

Lines changed: 0 additions & 142 deletions
This file was deleted.

Libraries/src/Amazon.Lambda.AspNetCoreServer.Hosting/ServiceCollectionExtensions.cs

Lines changed: 20 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -90,20 +90,23 @@ public static IServiceCollection AddAWSLambdaHosting(this IServiceCollection ser
9090

9191
#if NET8_0_OR_GREATER
9292
/// <summary>
93-
/// Adds a function meant to initialize the asp.net and lambda pipelines during <see cref="SnapshotRestore.RegisterBeforeSnapshot"/>
94-
/// improving the performance gains offered by SnapStart.
93+
/// Adds a <see cref="HttpRequestMessage"/>> that will be used to invoke
94+
/// Routes in your lambda function in order to initialize the ASP.NET Core and Lambda pipelines
95+
/// during <see cref="SnapshotRestore.RegisterBeforeSnapshot"/>. This improves the performance gains
96+
/// offered by SnapStart.
9597
/// <para />
96-
/// Pass a function with one or more <see cref="HttpRequestMessage"/>s that will be used to invoke
97-
/// Routes in your lambda function. The returned <see cref="HttpRequestMessage"/> must have a relative
98+
/// The returned <see cref="HttpRequestMessage"/> must have a relative
9899
/// <see cref="HttpRequestMessage.RequestUri"/>.
99100
/// <para />.
100101
/// Be aware that this will invoke your applications function handler code
101-
/// multiple times. Additionally, it uses a mock <see cref="ILambdaContext"/>
102-
/// which may not be fully populated.
102+
/// multiple times so that .NET runtime sees this code is a hot path and should be optimized.
103+
/// <para />
104+
/// When the function handler is called as part of SnapStart warm up, the instance will use a
105+
/// mock <see cref="ILambdaContext"/>, which will not be fully populated.
103106
/// <para />
104107
/// This method automatically registers with <see cref="SnapshotRestore.RegisterBeforeSnapshot"/>.
105108
/// <para />
106-
/// If SnapStart is not enabled, then this method is ignored and <paramref name="beforeSnapStartRequests"/> is never invoked.
109+
/// This method can be called multiple times to register additional urls.
107110
/// <para />
108111
/// Example:
109112
/// <para />
@@ -115,9 +118,9 @@ public static IServiceCollection AddAWSLambdaHosting(this IServiceCollection ser
115118
/// builder.Services.AddAWSLambdaHosting(LambdaEventSource.HttpApi);
116119
///
117120
/// // Initialize asp.net pipeline before Snapshot
118-
/// builder.Services.AddAWSLambdaBeforeSnapshotRequest(() => [
121+
/// builder.Services.AddAWSLambdaBeforeSnapshotRequest(
119122
/// new HttpRequestMessage(HttpMethod.Get, "/test")
120-
/// });
123+
/// );
121124
///
122125
/// var app = builder.Build();
123126
///
@@ -127,29 +130,18 @@ public static IServiceCollection AddAWSLambdaHosting(this IServiceCollection ser
127130
/// ]]>
128131
/// </code>
129132
/// </summary>
130-
#else
131-
/// <summary>
132-
/// Snapstart requires your application to target .NET 8 or above.
133-
/// </summary>
134-
#endif
135-
public static IServiceCollection AddAWSLambdaBeforeSnapshotRequest(this IServiceCollection services, Func<IEnumerable<HttpRequestMessage>> beforeSnapStartRequests)
133+
/// <param name="services"></param>
134+
/// <param name="beforeSnapStartRequest"></param>
135+
public static IServiceCollection AddAWSLambdaBeforeSnapshotRequest(this IServiceCollection services, HttpRequestMessage beforeSnapStartRequest)
136136
{
137-
#if NET8_0_OR_GREATER
138-
LambdaSnapstartExecuteRequestsBeforeSnapshotHelper.Registrar.Register(beforeSnapStartRequests);
139-
#endif
137+
services.AddSingleton(new GetBeforeSnapshotRequestsCollector
138+
{
139+
Requests = beforeSnapStartRequest
140+
});
140141

141142
return services;
142143
}
143-
144-
/// <inheritdoc cref="AddAWSLambdaBeforeSnapshotRequest(IServiceCollection,Func{IEnumerable{HttpRequestMessage}})"/>
145-
public static IServiceCollection AddAWSLambdaBeforeSnapshotRequest(this IServiceCollection services, Func<HttpRequestMessage> beforeSnapStartRequest)
146-
{
147-
return AddAWSLambdaBeforeSnapshotRequest(services,
148-
() => new List<HttpRequestMessage>
149-
{
150-
beforeSnapStartRequest()
151-
});
152-
}
144+
#endif
153145

154146
private static bool TryLambdaSetup(IServiceCollection services, LambdaEventSource eventSource, Action<HostingOptions>? configure, out HostingOptions? hostingOptions)
155147
{
@@ -174,11 +166,6 @@ private static bool TryLambdaSetup(IServiceCollection services, LambdaEventSourc
174166

175167
Utilities.EnsureLambdaServerRegistered(services, serverType);
176168

177-
#if NET8_0_OR_GREATER
178-
// register a LambdaSnapStartInitializerHttpMessageHandler
179-
services.AddSingleton<LambdaSnapstartExecuteRequestsBeforeSnapshotHelper>(new LambdaSnapstartExecuteRequestsBeforeSnapshotHelper(eventSource));
180-
#endif
181-
182169
return true;
183170
}
184171
}

0 commit comments

Comments
 (0)