Skip to content

Commit 763280b

Browse files
[release/9.4] Force async execution of resource startup (#10360)
* Force async execution of resource startup - Previously we didn't preemptively dispatch to the threadpool per resource on startup. That causes issues blocking other resource's startup because of a single blocking call. This change dispatching preemptively before creating the dcp resource. * Refactor ParameterResource to use Lazy initialization for value retrieval (#10361) --------- Co-authored-by: David Fowler <davidfowl@gmail.com>
1 parent ce25be6 commit 763280b

File tree

2 files changed

+9
-14
lines changed

2 files changed

+9
-14
lines changed

src/Aspire.Hosting/ApplicationModel/ParameterResource.cs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ namespace Aspire.Hosting.ApplicationModel;
88
/// </summary>
99
public class ParameterResource : Resource, IResourceWithoutLifetime, IManifestExpressionProvider, IValueProvider
1010
{
11-
private string? _value;
12-
private bool _hasValue;
11+
private readonly Lazy<string> _lazyValue;
1312
private readonly Func<ParameterDefault?, string> _valueGetter;
1413
private string? _configurationKey;
1514

@@ -25,6 +24,7 @@ public ParameterResource(string name, Func<ParameterDefault?, string> callback,
2524
ArgumentNullException.ThrowIfNull(callback);
2625

2726
_valueGetter = callback;
27+
_lazyValue = new Lazy<string>(() => _valueGetter(Default));
2828
Secret = secret;
2929
}
3030

@@ -33,18 +33,7 @@ public ParameterResource(string name, Func<ParameterDefault?, string> callback,
3333
/// </summary>
3434
public string Value => GetValueAsync(default).AsTask().GetAwaiter().GetResult()!;
3535

36-
internal string ValueInternal
37-
{
38-
get
39-
{
40-
if (!_hasValue)
41-
{
42-
_value = _valueGetter(Default);
43-
_hasValue = true;
44-
}
45-
return _value!;
46-
}
47-
}
36+
internal string ValueInternal => _lazyValue.Value;
4837

4938
/// <summary>
5039
/// Represents how the default value of the parameter should be retrieved.

src/Aspire.Hosting/Dcp/DcpExecutor.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,6 +1097,9 @@ async Task CreateResourceExecutablesAsyncCore(IResource resource, IEnumerable<Ap
10971097

10981098
private async Task CreateExecutableAsync(AppResource er, ILogger resourceLogger, CancellationToken cancellationToken)
10991099
{
1100+
// Force async execution
1101+
await Task.Yield();
1102+
11001103
if (er.DcpResource is not Executable exe)
11011104
{
11021105
throw new InvalidOperationException($"Expected an Executable resource, but got {er.DcpResource.Kind} instead");
@@ -1348,6 +1351,9 @@ async Task CreateContainerAsyncCore(AppResource cr, CancellationToken cancellati
13481351

13491352
private async Task CreateContainerAsync(AppResource cr, ILogger resourceLogger, CancellationToken cancellationToken)
13501353
{
1354+
// Force async execution
1355+
await Task.Yield();
1356+
13511357
await _executorEvents.PublishAsync(new OnResourceStartingContext(cancellationToken, KnownResourceTypes.Container, cr.ModelResource, cr.DcpResource.Metadata.Name)).ConfigureAwait(false);
13521358

13531359
var dcpContainerResource = (Container)cr.DcpResource;

0 commit comments

Comments
 (0)