Skip to content

QuotaUsageObserver

Namespace AgentPrism · Assembly AgentPrism.Core.dll

Cached data source for the agentprism.quota.usage/agentprism.quota.limit observable gauges.

public sealed class QuotaUsageObserver : IHostedService, IDisposable

objectQuotaUsageObserver

IHostedService, IDisposable

object.GetType(), object.ToString(), object.Equals(object?), object.Equals(object?, object?), object.ReferenceEquals(object?, object?), object.GetHashCode()

The ObservableGauge callback is synchronous; a database read CANNOT be done directly inside it. This class compares the cache’s age against AgentPrismObservabilityOptions.QuotaUsageRefreshInterval on every callback: if the cache is fresh it returns directly, if it is stale it refreshes ONCE (blocking). If consecutive polls fall within this interval, no second database query happens.

As long as AgentPrismObservabilityOptions.EnableQuotaUsageGauge is false, the cache is NEVER touched — the instrument name still exists (so it can be turned on without changing the consumer’s OTel configuration), but no measurement is published and the database is never queried.

Known limitation: tenant registration (ITenantStore) is not mandatory; this gauge only scans REGISTERED tenants. A quota rule for an unregistered tenant is still enforced correctly by QuotaEnforcer, it simply does not APPEAR on this dashboard. This is an accepted limitation given the phase’s “no new table/endpoint” goal.

QuotaUsageObserver(IQuotaStore, ITenantStore, IOptionsMonitor<AgentPrismOptions>, IOptionsMonitor<AgentPrismQuotaOptions>, IMeterFactory?, TimeProvider?, ILogger<QuotaUsageObserver>?)

Section titled “ QuotaUsageObserver(IQuotaStore, ITenantStore, IOptionsMonitor<AgentPrismOptions>, IOptionsMonitor<AgentPrismQuotaOptions>, IMeterFactory?, TimeProvider?, ILogger<QuotaUsageObserver>?)”

Creates a new quota gauge.

public QuotaUsageObserver(IQuotaStore quotaStore, ITenantStore tenantStore, IOptionsMonitor<AgentPrismOptions> options, IOptionsMonitor<AgentPrismQuotaOptions> quotaOptions, IMeterFactory? meterFactory = null, TimeProvider? timeProvider = null, ILogger<QuotaUsageObserver>? logger = null)

quotaStore IQuotaStore

The quota rule and counter store.

tenantStore ITenantStore

The store of registered tenants.

options IOptionsMonitor<AgentPrismOptions>

The root type that AgentPrismOptions.Observability, which carries the gauge on/off and cache interval settings, hangs off. AgentPrismObservabilityOptions is not registered standalone anywhere with services.Configure<AgentPrismObservabilityOptions> — it is only reached through AgentPrismOptions.Observability.

quotaOptions IOptionsMonitor<AgentPrismQuotaOptions>

The time-zone setting for the quota period calculation.

meterFactory IMeterFactory?

The meter factory. If null, a private Metrics.Meter instance is created and owned by this object.

timeProvider TimeProvider?

The time source. If null, TimeProvider.System.

logger ILogger<QuotaUsageObserver>?

The logger that cache-refresh errors are logged to.

ArgumentNullException

A required dependency is null.

public void Dispose()

Does nothing extra — the constructor already creates the instruments at REGISTRATION time. The only purpose of adding this type as an IHostedService is to make the container resolve and construct this object EARLY (while the host is starting); otherwise the instruments would never be created unless some consumer happens to resolve it.

public Task StartAsync(CancellationToken cancellationToken)

cancellationToken CancellationToken

The cancellation token.

Task

A completed task.

public Task StopAsync(CancellationToken cancellationToken)

cancellationToken CancellationToken

Task