MaintenanceService
Reads and changes maintenance mode. Application code depends on IMaintenanceService.
State is held in maintenance.json under the application content root and cached in memory, with writes updating the cache directly so a change takes effect on the next request whether or not the file watcher fires.
WARNING
Each instance keeps its own file and its own cache. In a multi-instance deployment, either point every instance at a shared content root or call EnableAsync on each one, or some instances stay online while others do not. Editing maintenance.json by hand relies on the file watcher, which does not fire reliably on container bind mounts or network filesystems.
GetAsync
Returns the current MaintenanceState. With no state file, it returns a disabled state built from the configured defaults.
When AutoDisableWhenExpired is on and EndsAt has passed, the state file is cleared and a disabled state is returned.
An unparseable state file is treated as enabled, so a damaged file cannot silently reopen an application that was meant to be closed. A file that merely cannot be read right now, because another process holds it or storage is briefly unavailable, is retried and then falls back to the last known state instead.
using AlmightyShogun.AspNet.MaintenanceMode;
public sealed class MaintenanceStatus(
IMaintenanceService maintenanceService
)
{
public Task<MaintenanceState> GetStatusAsync()
=> maintenanceService.GetAsync();
}Type signature
public Task<MaintenanceState> GetAsync();IsEnabledAsync
Whether maintenance mode is on. Reads the same state as GetAsync, including the expiry and read-failure handling.
This reports whether maintenance mode is enabled, not whether traffic is currently blocked. A window with a future StartsAt is enabled while requests are still served normally.
using AlmightyShogun.AspNet.MaintenanceMode;
public sealed class MaintenanceBanner(
IMaintenanceService maintenanceService
)
{
public Task<bool> ShouldShowAsync()
=> maintenanceService.IsEnabledAsync();
}Type signature
public Task<bool> IsEnabledAsync();EnableAsync
Turns maintenance mode on and writes the state file. Values on MaintenanceRequest apply to this window; omitted values fall back to MaintenanceSettings.
Calling it while a window is already active replaces that window rather than merging with it. A request whose EndsAt is at or before its StartsAt throws ArgumentException, so a window that could never be open is rejected before anything is written.
using AlmightyShogun.AspNet.MaintenanceMode;
public sealed class DeploymentMaintenance(
IMaintenanceService maintenanceService
)
{
public Task StartAsync()
=> maintenanceService.EnableAsync(new MaintenanceRequest
{
Message = "Deployment in progress.",
EndsAt = DateTimeOffset.UtcNow.AddMinutes(15),
AutoDisableWhenExpired = true,
RedirectBlockedRequests = false
});
}Type signature
public Task EnableAsync(MaintenanceRequest request);DisableAsync
Turns maintenance mode off by removing the persisted state. Configuration defaults are untouched, so the next EnableAsync starts from them again.
using AlmightyShogun.AspNet.MaintenanceMode;
public sealed class DeploymentMaintenance(
IMaintenanceService maintenanceService
)
{
public Task FinishAsync()
=> maintenanceService.DisableAsync();
}Type signature
public Task DisableAsync();