NotableDateCachingOptions Class
Definition
- Namespace
- Bodu.Globalization.Calendar.Caching
- Assembly
- Bodu.Globalization.Calendar.Caching.dll
- Package
- Bodu.Globalization.Calendar.Caching 1.0.0
Configures a CachingNotableDateService: how long a computed year stays fresh, the resource-version token used when no resource provider is observed, the on-disk cache location, and the log levels of the per-lookup hit and miss diagnostics.
public sealed class NotableDateCachingOptions
- Inheritance
-
NotableDateCachingOptions
- Inherited Members
- Extension Methods
Remarks
Every member carries a working default, so the options bind cleanly through Microsoft.Extensions.Options and
require no configuration for the common case.
Freshness has two independent triggers. Ttl expires a cached year a fixed duration after it was computed, a safety net against drift. A change in the resource currently in effect changes the version token and invalidates every entry computed under the previous version, so a reload always forces a recompute regardless of the time-to-live.
Constructors
NotableDateCachingOptions()
public NotableDateCachingOptions()
Properties
CacheDirectory
Gets or sets the directory used by the default on-disk cache.
public string? CacheDirectory { get; set; }
Property Value
CacheHitLogLevel
Gets or sets the level at which a year served from the cache is logged.
public LogLevel CacheHitLogLevel { get; set; }
Property Value
- LogLevel
The log level; defaults to Information.
CacheMissLogLevel
Gets or sets the level at which a year recomputed on a cache miss and cached is logged.
public LogLevel CacheMissLogLevel { get; set; }
Property Value
- LogLevel
The log level; defaults to Information.
RefreshAheadFraction
Gets or sets the fraction of the effective time-to-live after which a cache hit, while still served immediately, additionally schedules a single background recompute of the served year, so a hot territory is recomputed before it expires and no caller ever absorbs the recompute latency.
public double RefreshAheadFraction { get; set; }
Property Value
- double
A fraction in
[0, 1); defaults to0, which disables refresh-ahead entirely and preserves the plain serve-until-expiry behaviour.
Remarks
Refresh-ahead is access-triggered: no timers run, and only a year actually served from the cache can schedule a
recompute. When a hit's served entry is older than this fraction of the effective (post-jitter) time-to-live, at
most one background recompute per territory, year, and resource version is started; concurrent aged hits for the
same key join the pending recompute rather than duplicating it. Because the fraction is below 1, the
recompute always begins before the entry expires, so a continuously hot territory never surfaces a miss.
The background recompute shares the single-flight guard with genuine misses, so a miss that arrives while a refresh is computing is served the refreshed value; such a joining caller is counted as neither a hit nor a miss. A recompute that fails is swallowed after logging - the hit it piggybacked on was already served - and the next aged hit schedules a fresh attempt. Disposing the service prevents new recomputes from being scheduled and abandons pending ones without draining them.
ResourceVersion
Gets or sets the resource-version token used to key cache entries when the caching service observes no INotableDateResourceProvider.
public string? ResourceVersion { get; set; }
Property Value
- string
The fixed version token, or null to use a built-in default. Ignored when a resource provider is observed, in which case the token is derived from the resource in effect.
Remarks
Set this to the data version of the resource the wrapped service resolves against when that service is not reloadable, so bumping it invalidates the cache after a data update. When a reloadable resource provider is observed, the token is derived from the resource identity and reload generation instead and this value is unused.
Ttl
Gets or sets the duration a computed year stays fresh after it was computed.
public TimeSpan Ttl { get; set; }
Property Value
- TimeSpan
The time-to-live; defaults to 30 days.
Remarks
Validation requires only a strictly positive duration; there is no upper bound. Because notable-date resolution is deterministic for a given resource version, the version trigger handles data changes and this time-to-live is a coarse safety net; an extreme duration effectively disables the time-based trigger.
TtlJitter
Gets or sets the maximum fraction of Ttl that is deterministically shaved off per territory, so territories warmed together do not all expire - and recompute - at the same instant.
public double TtlJitter { get; set; }
Property Value
- double
A fraction in
[0, 1); defaults to0, which disables jitter and preserves the exact configured time-to-live.
Remarks
The reduction is derived from a stable hash of the normalized territory (not from randomness), so a given territory's effective time-to-live is identical across instances and processes and deterministic under test. The jitter is keyed by territory rather than by territory and year so the batch and per-year read paths - which share one time-to-live per resolution - always agree on freshness. Jitter only ever shortens the duration, so no year is served longer than the configured time-to-live allows; the trade-off is that a territory may recompute up to this fraction of its time-to-live early.
Methods
TryValidate(out string?)
Attempts to validate the options without throwing, reporting the first invariant that is violated.
public bool TryValidate(out string? error)
Parameters
errorstringWhen this method returns false, a message describing the first violated invariant; otherwise null.
Returns
Validate()
Validates the option values, throwing when a rule is violated.
public void Validate()
Remarks
This throwing form preserves the ParamName of the offending option. The dependency-injection registration
instead wires TryValidate(out string?) into ValidateOnStart.
Exceptions
- ArgumentException
Thrown when Ttl is not strictly positive, or when CacheHitLogLevel or CacheMissLogLevel is not a defined LogLevel.
Applies to
| Product | Versions |
|---|---|
| .NET | 8, 10 |