Skip to content

Commit

Permalink
Default Shell State Consistency (OrchardCMS#12174)
Browse files Browse the repository at this point in the history
  • Loading branch information
jtkech authored Aug 15, 2022
1 parent f4c3d8f commit e158e59
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 7 deletions.
13 changes: 10 additions & 3 deletions src/OrchardCore/OrchardCore/Modules/ModularBackgroundService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,15 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)

if (_options.ShellWarmup)
{
// Ensure all ShellContext are loaded and available.
await _shellHost.InitializeAsync();
try
{
// Ensure all tenants are pre-loaded.
await _shellHost.InitializeAsync();
}
catch (Exception ex) when (!ex.IsFatal())
{
_logger.LogError(ex, "Failed to warm up the tenants from '{ServiceName}'.", nameof(ModularBackgroundService));
}
}

while (GetRunningShells().Count() < 1)
Expand Down Expand Up @@ -93,7 +100,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
}
catch (Exception ex) when (!ex.IsFatal())
{
_logger.LogError(ex, "Error while executing '{ServiceName}'", nameof(ModularBackgroundService));
_logger.LogError(ex, "Error while executing '{ServiceName}'.", nameof(ModularBackgroundService));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ public DistributedShellHostedService(
/// </summary>
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
// The syncing period in seconds of the default tenant while it is 'Uninitialized'.
const int DefaultTenantSyncingPeriod = 20;

stoppingToken.Register(() =>
{
_logger.LogInformation("'{ServiceName}' is stopping.", nameof(DistributedShellHostedService));
Expand All @@ -72,6 +75,9 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
// Init the idle time.
var idleTime = MinIdleTime;

// Init the second counter used to sync the default tenant while it is 'Uninitialized'.
var defaultTenantSyncingSeconds = 0;

while (!stoppingToken.IsCancellationRequested)
{
try
Expand All @@ -82,9 +88,35 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
break;
}

// If there is no default tenant or it is not running, nothing to do.
if (!_shellHost.TryGetShellContext(ShellHelper.DefaultShellName, out var defaultContext) ||
defaultContext.Settings.State != TenantState.Running)
// If there is no default tenant, nothing to do.
if (!_shellHost.TryGetShellContext(ShellHelper.DefaultShellName, out var defaultContext))
{
continue;
}

// Manage the second counter used to sync the default tenant while it is 'Uninitialized'.
defaultTenantSyncingSeconds = defaultContext.Settings.State == TenantState.Uninitialized
? defaultTenantSyncingSeconds++
: 0;

// Check periodically if the default tenant is still 'Uninitialized'.
if (defaultTenantSyncingSeconds++ > DefaultTenantSyncingPeriod)
{
defaultTenantSyncingSeconds = 0;

// Load the settings of the default tenant that may have been setup by another instance.
var defaultSettings = await _shellSettingsManager.LoadSettingsAsync(ShellHelper.DefaultShellName);
if (defaultSettings.State == TenantState.Running)
{
// If the default tenant has been setup by another instance, reload it locally.
await _shellHost.ReloadShellContextAsync(defaultContext.Settings, eventSource: false);
}

continue;
}

// If the default tenant is not running, nothing to do.
if (defaultContext.Settings.State != TenantState.Running)
{
continue;
}
Expand Down
2 changes: 1 addition & 1 deletion src/OrchardCore/OrchardCore/Shell/ShellHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ public async Task InitializeAsync()
if (!_initialized)
{
await PreCreateAndRegisterShellsAsync();
_initialized = true;
}
}
finally
{
_initialized = true;
_initializingSemaphore.Release();
}
}
Expand Down

0 comments on commit e158e59

Please sign in to comment.