RateCacheRules Class
Definition
- Namespace
- Bodu.Financial.ExchangeRates.Caching
- Assembly
- Bodu.Financial.ExchangeRates.Caching.dll
- Package
- Bodu.Financial.ExchangeRates.Caching 1.0.0
- Source
- RateCacheRules.cs
Provides the storage-agnostic freshness, validity, merge, and coverage rules shared by every IRateCache implementation, so the in-memory, file, SQLite, and distributed backends apply one authoritative policy and differ only in how they read and write their bytes.
public static class RateCacheRules
- Inheritance
-
RateCacheRules
- Inherited Members
Remarks
Every method operates on the public CachedRate row type and on a plain
(Start, End, FetchedAtUtc) coverage tuple, so a backend can call these rules without exposing its internal
state representation. The rules are pure: they read their inputs, evaluate freshness and validity against the
supplied instant, and return new collections, leaving all persistence and locking to the caller.
Freshness is a strict less-than comparison - a row or window exactly one duration old is stale - and validity allows a one-minute clock-skew tolerance so a row stamped marginally ahead of the evaluating clock is not discarded. These are the same thresholds the cache surface has always applied; centralising them here keeps every backend identical, which the shared cache contract tests assert.
Methods
BuildCoverage(IEnumerable<(DateOnly Start, DateOnly End, DateTimeOffset FetchedAtUtc)>, TimeSpan, DateTimeOffset)
Folds the still-fresh coverage windows for a pair into a DateRangeCoverage, evaluated against
asOf.
public static DateRangeCoverage BuildCoverage(IEnumerable<(DateOnly Start, DateOnly End, DateTimeOffset FetchedAtUtc)> windows, TimeSpan duration, DateTimeOffset asOf)
Parameters
windowsIEnumerable<(DateOnly Start, DateOnly End, DateTimeOffset FetchedAtUtc)>The recorded coverage windows to fold.
durationTimeSpanThe duration a recorded coverage window remains fresh after it was fetched.
asOfDateTimeOffsetThe instant against which coverage freshness is evaluated.
Returns
- DateRangeCoverage
A DateRangeCoverage describing the days known to have been fetched and still fresh; empty when no fresh window remains.
Exceptions
- ArgumentNullException
Thrown when
windowsis null.
IsValid(CachedRate, DateTimeOffset)
Reports whether a cached row is semantically valid against the evaluation instant.
public static bool IsValid(CachedRate row, DateTimeOffset asOf)
Parameters
rowCachedRateThe cached row to validate.
asOfDateTimeOffsetThe instant against which the caching instant is checked for implausible future stamps.
Returns
- bool
false when the row carries a non-positive rate, a default (unset) date, or a caching instant implausibly far in the future of
asOf; otherwise true.
Remarks
Invalid rows are silently skipped on both write (rejecting bad incoming data) and read (rejecting persisted or tampered rows) so a malformed cache never surfaces a nonsensical rate. A small clock-skew tolerance is allowed so a row stamped marginally ahead of the evaluating clock is not discarded.
MergeCoverage(IEnumerable<(DateOnly Start, DateOnly End, DateTimeOffset FetchedAtUtc)>, DateOnly, DateOnly, TimeSpan, DateTimeOffset)
Appends the newly fetched window start..end stamped at
asOf to the still-fresh existing windows, dropping windows that are no longer fresh.
public static List<(DateOnly Start, DateOnly End, DateTimeOffset FetchedAtUtc)> MergeCoverage(IEnumerable<(DateOnly Start, DateOnly End, DateTimeOffset FetchedAtUtc)> existing, DateOnly start, DateOnly end, TimeSpan duration, DateTimeOffset asOf)
Parameters
existingIEnumerable<(DateOnly Start, DateOnly End, DateTimeOffset FetchedAtUtc)>The windows already recorded for the pair.
startDateOnlyThe inclusive first date of the newly fetched range.
endDateOnlyThe inclusive last date of the newly fetched range.
durationTimeSpanThe duration a recorded coverage window remains fresh after it was fetched.
asOfDateTimeOffsetThe instant the new window is stamped with and against which stale windows are pruned.
Returns
- List<(DateOnly Start, DateOnly End, DateTimeOffset FetchedAtUtc)>
The pruned existing windows with the new window appended.
Exceptions
- ArgumentNullException
Thrown when
existingis null.- ArgumentOutOfRangeException
Thrown when
startis later thanend.
MergeRows(IEnumerable<CachedRate>, IEnumerable<CachedRate>, TimeSpan, DateTimeOffset)
Merges incoming rows into existing rows so the most recently cached row
wins per date, dropping rows that are stale or semantically invalid, and ordering the result by date.
public static List<CachedRate> MergeRows(IEnumerable<CachedRate> existing, IEnumerable<CachedRate> incoming, TimeSpan duration, DateTimeOffset asOf)
Parameters
existingIEnumerable<CachedRate>The rows already stored for the pair.
incomingIEnumerable<CachedRate>The rows being stored, which take precedence on a tie by caching instant.
durationTimeSpanThe duration a cached row remains fresh after it was cached.
asOfDateTimeOffsetThe instant against which staleness and validity are evaluated.
Returns
- List<CachedRate>
The merged, pruned rows ordered ascending by date; empty when none survive.
Remarks
An incoming invalid row is skipped before it can overwrite a valid stored row for the same date. After the merge, every surviving row is re-checked for freshness and validity so the store self-cleans on each write.
Exceptions
- ArgumentNullException
Thrown when
existingorincomingis null.
SelectFresh(IEnumerable<CachedRate>, TimeSpan, DateTimeOffset)
Selects the rows that are both semantically valid and still fresh at asOf, ordered by date.
public static List<CachedRate> SelectFresh(IEnumerable<CachedRate> rows, TimeSpan duration, DateTimeOffset asOf)
Parameters
rowsIEnumerable<CachedRate>The candidate rows to filter.
durationTimeSpanThe duration a cached row remains fresh after it was cached.
asOfDateTimeOffsetThe instant against which freshness and validity are evaluated.
Returns
- List<CachedRate>
The fresh, valid rows ordered ascending by date; empty when none qualify.
Exceptions
- ArgumentNullException
Thrown when
rowsis null.
Applies to
| Product | Versions |
|---|---|
| .NET | 8, 10 |