Table of Contents

Interface IMonitoringStorage

Namespace
Millrace.Storage.Monitoring
Assembly
Millrace.dll

The dashboard read model (ARCHITECTURE.md §4.1). Separate from IJobStorage so the hot path stays lean, but required of a supported provider (§11.14): a provider that omits it leaves the dashboard blank, so MapMillraceDashboard fails at startup naming the provider rather than letting an end user discover it.

public interface IMonitoringStorage

Remarks

Reads are not linearized against the hot path. These queries are allowed to observe a slightly stale snapshot and MUST NOT take locks that could delay claiming or applying a transition. A job may change state between appearing in a page and being fetched by id; callers treat every result as a point-in-time observation.

Paging is keyset, ordered CreatedAt DESC, Id DESC (§11.12). Within that ordering a full traversal never returns the same row twice and never skips a row that existed, unchanged and matching, for the whole traversal. Rows that change state mid-traversal may appear or vanish — no pagination scheme can prevent that, and the contract does not pretend otherwise.

Cursors are opaque and provider-defined. A provider MUST reject a cursor it cannot decode — malformed or truncated — with MillraceStorageException. Silently treating an unrecognized cursor as "start from the beginning" would turn a client bug into an infinite paging loop. Providers sharing an encoding (as the bundled ones do, via MonitoringCursor) will decode each other's cursors; that is harmless, since a dashboard is bound to one provider and a cursor cannot legitimately cross between them.

Tenancy. Every query carries a TenantFilter; providers apply it exactly, distinguishing "any tenant" from "the untenanted scope". This interface performs no authorization of its own — the dashboard decides who may ask (§11.13).

Methods

GetJobDetailsAsync(JobId, CancellationToken)

Full detail for one job, or null if no such job exists.

GetStatisticsAsync(TenantFilter, CancellationToken)

Aggregate counts for the overview, scoped by tenant.

QueryInstancesAsync(InstanceQuery, CancellationToken)

One page of workflow instances matching query. Same paging, cursor and tenancy rules as QueryJobsAsync(JobQuery, CancellationToken).

QueryJobsAsync(JobQuery, CancellationToken)

One page of jobs matching query.

QueryRecurringAsync(RecurringQuery, CancellationToken)

One page of recurring definitions matching query, ordered NextFireTime ASC, Id ASC.