SingletonGuard
AgentPrism.Core.dllReduces a background service’s execution to a single instance cluster-wide.
public sealed class SingletonGuardInheritance
Section titled “Inheritance”Inherited Members
Section titled “Inherited Members”object.GetType(), object.ToString(), object.Equals(object?), object.Equals(object?, object?), object.ReferenceEquals(object?, object?), object.GetHashCode()
Remarks
Section titled “Remarks”SingletonGuard.RunAsync runs its own lease/renew loop at an interval that is ONE THIRD of SingletonExecutionOptions.LeaseDuration; this keeps the lease alive in cases where the calling service’s own work interval (e.g. MCP discovery’s 5-minute refresh interval) may be much longer than the lease duration. The calling service reads only SingletonGuard.IsHeld on each of its own ticks - this is synchronous and free, it produces no extra database round-trip.
While SingletonExecutionOptions.Enabled is false (the default), SingletonGuard.RunAsync returns immediately without issuing ANY query to the store, and SingletonGuard.IsHeld always stays true - today’s single-instance behavior is preserved exactly.
This type is not internal, it is public: it needs to be
usable from a separate assembly such as AgentPrism.Mcp, and
InternalsVisibleTo covers only its own test projects, not sibling
packages. This is why the plan’s suggestion of an “internal helper” could
not be implemented.
Constructors
Section titled “Constructors”SingletonGuard(ISingletonLeaseStore, IOptionsMonitor<SingletonExecutionOptions>, string, ILogger?)
Section titled “ SingletonGuard(ISingletonLeaseStore, IOptionsMonitor<SingletonExecutionOptions>, string, ILogger?)”Creates a new single-executor guard.
public SingletonGuard(ISingletonLeaseStore store, IOptionsMonitor<SingletonExecutionOptions> optionsMonitor, string leaseName, ILogger? logger = null)Parameters
Section titled “Parameters”store ISingletonLeaseStore
Lease store.
optionsMonitor IOptionsMonitor<SingletonExecutionOptions>
Single-executor selection settings.
leaseName string
Cluster-wide unique name of the protected work.
logger ILogger?
Logger to which lease-loss and error logs are written.
Exceptions
Section titled “Exceptions”store
or
optionsMonitor
is null.
leaseName is empty.
Properties
Section titled “Properties”IsHeld
Section titled “ IsHeld”Whether this instance currently holds the lease. Always true when single-executor selection is disabled. Synchronous; the calling service can read this on every tick for free.
public bool IsHeld { get; }Property Value
Section titled “Property Value”Methods
Section titled “Methods”RunAsync(CancellationToken)
Section titled “ RunAsync(CancellationToken)”Starts the lease/renew loop. Returns immediately without issuing ANY
query to the store when single-executor selection is disabled. When
stoppingToken is cancelled, the lease (if held) is
released and the task completes.
public Task RunAsync(CancellationToken stoppingToken)Parameters
Section titled “Parameters”stoppingToken CancellationToken
The host service’s stop token.
Returns
Section titled “Returns”The task representing the loop.