Skip to content

Commit 209439c

Browse files
Change lazy initialization default for HC Core
1 parent c6c491c commit 209439c

23 files changed

+465
-340
lines changed

src/All.slnx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
<Project Path="HotChocolate/AspNetCore/src/Transport.Sockets.Client/HotChocolate.Transport.Sockets.Client.csproj" />
4848
<Project Path="HotChocolate/AspNetCore/src/Transport.Sockets/HotChocolate.Transport.Sockets.csproj" />
4949
</Folder>
50-
<Folder Name="/HotChocolate/AspNetCore/src/AspNetCore/" />
5150
<Folder Name="/HotChocolate/AspNetCore/test/">
5251
<Project Path="HotChocolate/AspNetCore/test/AspNetCore.Authorization.Opa.Tests/HotChocolate.AspNetCore.Authorization.Opa.Tests.csproj" />
5352
<Project Path="HotChocolate/AspNetCore/test/AspNetCore.Authorization.Tests/HotChocolate.AspNetCore.Authorization.Tests.csproj" />
@@ -188,12 +187,12 @@
188187
<Folder Name="/HotChocolate/Fusion-vnext/test/">
189188
<Project Path="HotChocolate/Fusion-vnext/test/Fusion.AspNetCore.Tests/HotChocolate.Fusion.AspNetCore.Tests.csproj" />
190189
<Project Path="HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/HotChocolate.Fusion.Composition.Tests.csproj" />
191-
<Project Path="HotChocolate/Fusion-vnext/test/Fusion.Execution.Tests/HotChocolate.Fusion.Execution.Tests.csproj" />
192190
<Project Path="HotChocolate/Fusion-vnext/test/Fusion.EventSources.Tests/HotChocolate.Fusion.EventSources.Tests.csproj" />
191+
<Project Path="HotChocolate/Fusion-vnext/test/Fusion.Execution.Tests/HotChocolate.Fusion.Execution.Tests.csproj" />
193192
<Project Path="HotChocolate/Fusion-vnext/test/Fusion.Language.Tests/HotChocolate.Fusion.Language.Tests.csproj" />
194193
<Project Path="HotChocolate/Fusion-vnext/test/Fusion.Packaging.Tests/HotChocolate.Fusion.Packaging.Tests.csproj" />
195-
<Project Path="HotChocolate/Fusion-vnext/test/Fusion.Utilities.Tests/HotChocolate.Fusion.Utilities.Tests.csproj" />
196194
<Project Path="HotChocolate/Fusion-vnext/test/Fusion.Tests.Shared/HotChocolate.Fusion.Tests.Shared.csproj" />
195+
<Project Path="HotChocolate/Fusion-vnext/test/Fusion.Utilities.Tests/HotChocolate.Fusion.Utilities.Tests.csproj" />
197196
</Folder>
198197
<Folder Name="/HotChocolate/Language/" />
199198
<Folder Name="/HotChocolate/Language/src/">
@@ -288,12 +287,12 @@
288287
</Folder>
289288
<Folder Name="/HotChocolate/Utilities/" />
290289
<Folder Name="/HotChocolate/Utilities/src/">
290+
<Project Path="HotChocolate/Utilities/src/Utilities.Base36/HotChocolate.Utilities.Base36.csproj" />
291291
<Project Path="HotChocolate/Utilities/src/Utilities.Buffers/HotChocolate.Utilities.Buffers.csproj" />
292292
<Project Path="HotChocolate/Utilities/src/Utilities.DependencyInjection/HotChocolate.Utilities.DependencyInjection.csproj" />
293293
<Project Path="HotChocolate/Utilities/src/Utilities.Introspection/HotChocolate.Utilities.Introspection.csproj" />
294294
<Project Path="HotChocolate/Utilities/src/Utilities.Tasks/HotChocolate.Utilities.Tasks.csproj" />
295295
<Project Path="HotChocolate/Utilities/src/Utilities/HotChocolate.Utilities.csproj" />
296-
<Project Path="HotChocolate/Utilities/src/Utilities.Base36/HotChocolate.Utilities.Base36.csproj" />
297296
</Folder>
298297
<Folder Name="/HotChocolate/Utilities/test/">
299298
<Project Path="HotChocolate/Utilities/test/Utilities.Introspection.Tests/HotChocolate.Utilities.Introspection.Tests.csproj" />
@@ -353,4 +352,4 @@
353352
<Folder Name="/StrawberryShake/Tooling/test/">
354353
<Project Path="StrawberryShake/Tooling/test/Configuration.Tests/StrawberryShake.Tools.Configuration.Tests.csproj" />
355354
</Folder>
356-
</Solution>
355+
</Solution>
Lines changed: 160 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,139 +1,192 @@
1-
using HotChocolate.AspNetCore.Warmup;
1+
using System.Diagnostics.CodeAnalysis;
22
using HotChocolate.Execution.Configuration;
3-
using HotChocolate.Execution.Internal;
43

54
// ReSharper disable once CheckNamespace
65
namespace Microsoft.Extensions.DependencyInjection;
76

87
public static partial class HotChocolateAspNetCoreServiceCollectionExtensions
98
{
109
/// <summary>
11-
/// Adds the current GraphQL configuration to the warmup background service.
10+
/// Adds a warmup task that will be executed on each newly created request executor.
1211
/// </summary>
13-
/// <param name="builder">
14-
/// The <see cref="IRequestExecutorBuilder"/>.
15-
/// </param>
16-
/// <param name="warmup">
17-
/// The warmup task that shall be executed on a new executor.
18-
/// </param>
19-
/// <param name="keepWarm">
20-
/// Apply warmup task after eviction and keep executor in-memory.
21-
/// </param>
22-
/// <param name="skipIf">
23-
/// Skips the warmup task if set to true.
24-
/// </param>
25-
/// <returns>
26-
/// Returns the <see cref="IRequestExecutorBuilder"/> so that configuration can be chained.
27-
/// </returns>
28-
/// <exception cref="ArgumentNullException">
29-
/// The <see cref="IRequestExecutorBuilder"/> is <c>null</c>.
30-
/// </exception>
31-
public static IRequestExecutorBuilder InitializeOnStartup(
12+
public static IRequestExecutorBuilder AddWarmupTask(
3213
this IRequestExecutorBuilder builder,
33-
Func<IRequestExecutor, CancellationToken, Task>? warmup = null,
34-
bool keepWarm = false,
35-
bool skipIf = false)
14+
Func<IRequestExecutor, CancellationToken, Task> warmupFunc)
3615
{
3716
ArgumentNullException.ThrowIfNull(builder);
17+
ArgumentNullException.ThrowIfNull(warmupFunc);
3818

39-
if (!skipIf)
40-
{
41-
builder.Services.AddHostedService<RequestExecutorWarmupService>();
42-
builder.Services.AddSingleton(new WarmupSchemaTask(builder.Name, keepWarm, warmup));
43-
}
44-
45-
return builder;
19+
return builder.AddWarmupTask(new DelegateWarmupTask(warmupFunc));
4620
}
4721

4822
/// <summary>
49-
/// Adds the current GraphQL configuration to the warmup background service.
23+
/// Adds a warmup task that will be executed on each newly created request executor.
5024
/// </summary>
51-
/// <param name="builder">
52-
/// The <see cref="IRequestExecutorBuilder"/>.
53-
/// </param>
54-
/// <param name="options">
55-
/// The <see cref="RequestExecutorInitializationOptions"/>.
56-
/// </param>
57-
/// <param name="skipIf">
58-
/// Skips the warmup task if set to true.
59-
/// </param>
60-
/// <returns>
61-
/// Returns the <see cref="IRequestExecutorBuilder"/> so that configuration can be chained.
62-
/// </returns>
63-
/// <exception cref="ArgumentNullException">
64-
/// The <see cref="IRequestExecutorBuilder"/> is <c>null</c>.
65-
/// </exception>
66-
public static IRequestExecutorBuilder InitializeOnStartup(
25+
public static IRequestExecutorBuilder AddWarmupTask(
6726
this IRequestExecutorBuilder builder,
68-
RequestExecutorInitializationOptions options,
69-
bool skipIf = false)
27+
IRequestExecutorWarmupTask warmupTask)
7028
{
7129
ArgumentNullException.ThrowIfNull(builder);
30+
ArgumentNullException.ThrowIfNull(warmupTask);
7231

73-
if (skipIf)
74-
{
75-
return builder;
76-
}
77-
78-
Func<IRequestExecutor, CancellationToken, Task>? warmup;
79-
80-
if (options.WriteSchemaFile.Enable)
81-
{
82-
var schemaFileName =
83-
options.WriteSchemaFile.FileName
84-
?? System.IO.Path.Combine(Environment.CurrentDirectory, "schema.graphqls");
32+
builder.ConfigureSchemaServices((_, sc) => sc.AddSingleton(warmupTask));
8533

86-
if (options.Warmup is null)
87-
{
88-
warmup = async (executor, cancellationToken)
89-
=> await SchemaFileExporter.Export(schemaFileName, executor, cancellationToken);
90-
}
91-
else
92-
{
93-
warmup = async (executor, cancellationToken) =>
94-
{
95-
await SchemaFileExporter.Export(schemaFileName, executor, cancellationToken);
96-
await options.Warmup(executor, cancellationToken);
97-
};
98-
}
99-
}
100-
else
101-
{
102-
warmup = options.Warmup;
103-
}
104-
105-
return InitializeOnStartup(builder, warmup, options.KeepWarm);
34+
return builder;
10635
}
10736

10837
/// <summary>
109-
/// Exports the GraphQL schema to a file on startup or when the schema changes.
38+
/// Adds a warmup task that will be executed on each newly created request executor.
11039
/// </summary>
111-
/// <param name="builder">
112-
/// The <see cref="IRequestExecutorBuilder"/>.
113-
/// </param>
114-
/// <param name="schemaFileName">
115-
/// The file name of the schema file.
116-
/// </param>
117-
/// <returns>
118-
/// Returns the <see cref="IRequestExecutorBuilder"/> so that configuration can be chained.
119-
/// </returns>
120-
/// <exception cref="ArgumentNullException">
121-
/// The <see cref="IRequestExecutorBuilder"/> is <c>null</c>.
122-
/// </exception>
123-
public static IRequestExecutorBuilder ExportSchemaOnStartup(
124-
this IRequestExecutorBuilder builder,
125-
string? schemaFileName = null)
40+
public static IRequestExecutorBuilder AddWarmupTask<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] T>(
41+
this IRequestExecutorBuilder builder)
42+
where T : class, IRequestExecutorWarmupTask
12643
{
12744
ArgumentNullException.ThrowIfNull(builder);
12845

129-
return InitializeOnStartup(builder, new RequestExecutorInitializationOptions
46+
builder.ConfigureSchemaServices(
47+
static (_, sc) => sc.AddSingleton<IRequestExecutorWarmupTask, T>());
48+
49+
return builder;
50+
}
51+
52+
private sealed class DelegateWarmupTask(Func<IRequestExecutor, CancellationToken, Task> warmupFunc)
53+
: IRequestExecutorWarmupTask
54+
{
55+
public bool ApplyOnlyOnStartup => false;
56+
57+
public Task WarmupAsync(IRequestExecutor requestExecutor, CancellationToken cancellationToken)
13058
{
131-
KeepWarm = true,
132-
WriteSchemaFile = new SchemaFileInitializationOptions
133-
{
134-
Enable = true,
135-
FileName = schemaFileName
136-
}
137-
});
59+
return warmupFunc.Invoke(requestExecutor, cancellationToken);
60+
}
13861
}
62+
63+
// /// <summary>
64+
// /// Adds the current GraphQL configuration to the warmup background service.
65+
// /// </summary>
66+
// /// <param name="builder">
67+
// /// The <see cref="IRequestExecutorBuilder"/>.
68+
// /// </param>
69+
// /// <param name="warmup">
70+
// /// The warmup task that shall be executed on a new executor.
71+
// /// </param>
72+
// /// <param name="keepWarm">
73+
// /// Apply warmup task after eviction and keep executor in-memory.
74+
// /// </param>
75+
// /// <param name="skipIf">
76+
// /// Skips the warmup task if set to true.
77+
// /// </param>
78+
// /// <returns>
79+
// /// Returns the <see cref="IRequestExecutorBuilder"/> so that configuration can be chained.
80+
// /// </returns>
81+
// /// <exception cref="ArgumentNullException">
82+
// /// The <see cref="IRequestExecutorBuilder"/> is <c>null</c>.
83+
// /// </exception>
84+
// public static IRequestExecutorBuilder InitializeOnStartup(
85+
// this IRequestExecutorBuilder builder,
86+
// Func<IRequestExecutor, CancellationToken, Task>? warmup = null,
87+
// bool keepWarm = false,
88+
// bool skipIf = false)
89+
// {
90+
// ArgumentNullException.ThrowIfNull(builder);
91+
//
92+
// if (!skipIf)
93+
// {
94+
// builder.Services.AddHostedService<RequestExecutorWarmupService>();
95+
// builder.Services.AddSingleton(new WarmupSchemaTask(builder.Name, keepWarm, warmup));
96+
// }
97+
//
98+
// return builder;
99+
// }
100+
//
101+
// /// <summary>
102+
// /// Adds the current GraphQL configuration to the warmup background service.
103+
// /// </summary>
104+
// /// <param name="builder">
105+
// /// The <see cref="IRequestExecutorBuilder"/>.
106+
// /// </param>
107+
// /// <param name="options">
108+
// /// The <see cref="RequestExecutorInitializationOptions"/>.
109+
// /// </param>
110+
// /// <param name="skipIf">
111+
// /// Skips the warmup task if set to true.
112+
// /// </param>
113+
// /// <returns>
114+
// /// Returns the <see cref="IRequestExecutorBuilder"/> so that configuration can be chained.
115+
// /// </returns>
116+
// /// <exception cref="ArgumentNullException">
117+
// /// The <see cref="IRequestExecutorBuilder"/> is <c>null</c>.
118+
// /// </exception>
119+
// public static IRequestExecutorBuilder InitializeOnStartup(
120+
// this IRequestExecutorBuilder builder,
121+
// RequestExecutorInitializationOptions options,
122+
// bool skipIf = false)
123+
// {
124+
// ArgumentNullException.ThrowIfNull(builder);
125+
//
126+
// if (skipIf)
127+
// {
128+
// return builder;
129+
// }
130+
//
131+
// Func<IRequestExecutor, CancellationToken, Task>? warmup;
132+
//
133+
// if (options.WriteSchemaFile.Enable)
134+
// {
135+
// var schemaFileName =
136+
// options.WriteSchemaFile.FileName
137+
// ?? System.IO.Path.Combine(Environment.CurrentDirectory, "schema.graphqls");
138+
//
139+
// if (options.Warmup is null)
140+
// {
141+
// warmup = async (executor, cancellationToken)
142+
// => await SchemaFileExporter.Export(schemaFileName, executor, cancellationToken);
143+
// }
144+
// else
145+
// {
146+
// warmup = async (executor, cancellationToken) =>
147+
// {
148+
// await SchemaFileExporter.Export(schemaFileName, executor, cancellationToken);
149+
// await options.Warmup(executor, cancellationToken);
150+
// };
151+
// }
152+
// }
153+
// else
154+
// {
155+
// warmup = options.Warmup;
156+
// }
157+
//
158+
// return InitializeOnStartup(builder, warmup, options.KeepWarm);
159+
// }
160+
//
161+
// /// <summary>
162+
// /// Exports the GraphQL schema to a file on startup or when the schema changes.
163+
// /// </summary>
164+
// /// <param name="builder">
165+
// /// The <see cref="IRequestExecutorBuilder"/>.
166+
// /// </param>
167+
// /// <param name="schemaFileName">
168+
// /// The file name of the schema file.
169+
// /// </param>
170+
// /// <returns>
171+
// /// Returns the <see cref="IRequestExecutorBuilder"/> so that configuration can be chained.
172+
// /// </returns>
173+
// /// <exception cref="ArgumentNullException">
174+
// /// The <see cref="IRequestExecutorBuilder"/> is <c>null</c>.
175+
// /// </exception>
176+
// public static IRequestExecutorBuilder ExportSchemaOnStartup(
177+
// this IRequestExecutorBuilder builder,
178+
// string? schemaFileName = null)
179+
// {
180+
// ArgumentNullException.ThrowIfNull(builder);
181+
//
182+
// return InitializeOnStartup(builder, new RequestExecutorInitializationOptions
183+
// {
184+
// KeepWarm = true,
185+
// WriteSchemaFile = new SchemaFileInitializationOptions
186+
// {
187+
// Enable = true,
188+
// FileName = schemaFileName
189+
// }
190+
// });
191+
// }
139192
}

0 commit comments

Comments
 (0)