Skip to content

Commit a0406b1

Browse files
AndyButlandkjac
andauthored
Add defensive coding to the member application initializer (16) (#19764)
* Add defensive coding to the member application initializer (#19760) * Moved _isInitialized to after the initialization --------- Co-authored-by: kjac <[email protected]>
1 parent 93d61d0 commit a0406b1

File tree

1 file changed

+35
-7
lines changed

1 file changed

+35
-7
lines changed

src/Umbraco.Cms.Api.Delivery/Handlers/InitializeMemberApplicationNotificationHandler.cs

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Umbraco.Cms.Core.Notifications;
88
using Umbraco.Cms.Core.Security;
99
using Umbraco.Cms.Core.Services;
10+
using Umbraco.Cms.Core.Sync;
1011
using Umbraco.Cms.Infrastructure.Security;
1112

1213
namespace Umbraco.Cms.Api.Delivery.Handlers;
@@ -18,18 +19,24 @@ internal sealed class InitializeMemberApplicationNotificationHandler : INotifica
1819
private readonly DeliveryApiSettings _deliveryApiSettings;
1920
private readonly IServiceScopeFactory _serviceScopeFactory;
2021
private readonly IMemberClientCredentialsManager _memberClientCredentialsManager;
22+
private readonly IServerRoleAccessor _serverRoleAccessor;
23+
24+
private static readonly SemaphoreSlim _locker = new(1);
25+
private static bool _isInitialized = false;
2126

2227
public InitializeMemberApplicationNotificationHandler(
2328
IRuntimeState runtimeState,
2429
IOptions<DeliveryApiSettings> deliveryApiSettings,
2530
ILogger<InitializeMemberApplicationNotificationHandler> logger,
2631
IServiceScopeFactory serviceScopeFactory,
27-
IMemberClientCredentialsManager memberClientCredentialsManager)
32+
IMemberClientCredentialsManager memberClientCredentialsManager,
33+
IServerRoleAccessor serverRoleAccessor)
2834
{
2935
_runtimeState = runtimeState;
3036
_logger = logger;
3137
_serviceScopeFactory = serviceScopeFactory;
3238
_memberClientCredentialsManager = memberClientCredentialsManager;
39+
_serverRoleAccessor = serverRoleAccessor;
3340
_deliveryApiSettings = deliveryApiSettings.Value;
3441
}
3542

@@ -40,13 +47,34 @@ public async Task HandleAsync(UmbracoApplicationStartingNotification notificatio
4047
return;
4148
}
4249

43-
// we cannot inject the IMemberApplicationManager because it ultimately takes a dependency on the DbContext ... and during
44-
// install that is not allowed (no connection string means no DbContext)
45-
using IServiceScope scope = _serviceScopeFactory.CreateScope();
46-
IMemberApplicationManager memberApplicationManager = scope.ServiceProvider.GetRequiredService<IMemberApplicationManager>();
50+
if (_serverRoleAccessor.CurrentServerRole is ServerRole.Subscriber)
51+
{
52+
// subscriber instances should not alter the member application
53+
return;
54+
}
55+
56+
try
57+
{
58+
await _locker.WaitAsync(cancellationToken);
59+
if (_isInitialized)
60+
{
61+
return;
62+
}
4763

48-
await HandleMemberApplication(memberApplicationManager, cancellationToken);
49-
await HandleMemberClientCredentialsApplication(memberApplicationManager, cancellationToken);
64+
// we cannot inject the IMemberApplicationManager because it ultimately takes a dependency on the DbContext ... and during
65+
// install that is not allowed (no connection string means no DbContext)
66+
using IServiceScope scope = _serviceScopeFactory.CreateScope();
67+
IMemberApplicationManager memberApplicationManager = scope.ServiceProvider.GetRequiredService<IMemberApplicationManager>();
68+
69+
await HandleMemberApplication(memberApplicationManager, cancellationToken);
70+
await HandleMemberClientCredentialsApplication(memberApplicationManager, cancellationToken);
71+
72+
_isInitialized = true;
73+
}
74+
finally
75+
{
76+
_locker.Release();
77+
}
5078
}
5179

5280
private async Task HandleMemberApplication(IMemberApplicationManager memberApplicationManager, CancellationToken cancellationToken)

0 commit comments

Comments
 (0)