RcMap: Support updating idleTimeToLive when re-acquiring with longer TTL
Problem
With the recent addition of dynamic idleTimeToLive per key (#5858, implemented in #5859), the TTL is computed once at first acquisition time based on the key. However, there are use cases where the same resource needs different TTL values depending on the context of acquisition, and the TTL should be updated to the longest value seen across all active acquisitions.
We need this capability to implement https://github.com/livestorejs/livestore/issues/918, which requires updating the idle timeout for cached stores when multiple consumers request the same store with different retention requirements.
Current Behavior (after #5859)
The TTL is determined once at first acquisition time based on the key. If a resource is acquired with a 30s TTL, and later re-acquired requesting a 5 min TTL, the original 30s TTL remains unchanged.
Desired Behavior
When a resource is re-acquired with a longer TTL than currently stored, update the entry's TTL to the new (longer) value. The resource should adopt the longest TTL seen across all consumers.
Invariant: TTL should only ever increase, never decrease. This ensures resources are never disposed earlier than any consumer expects.
Proposed API
Option A: Extend existing get to accept TTL override
RcMap.get(map, key, options?: {
extendIdleTimeToLive?: Duration.DurationInput
}): Effect<A, E, Scope>
Option B: New getWithTTL function
RcMap.getWithTTL(
map,
key,
idleTimeToLive: Duration.DurationInput
): Effect<A, E, Scope>
Implementation Considerations
- Entry TTL update: When re-acquiring, compare the requested TTL with
entry.idleTimeToLiveand update if larger - Expiration recalculation: If
entry.expiresAtis set (resource is idle with pending disposal), extend it proportionally - Touch behavior:
touchshould continue using the (potentially updated)entry.idleTimeToLive - Thread safety: TTL updates must be atomic with respect to the release/expiration logic
Related Issues
- Builds on #5858 / #5859 (dynamic TTL per key at creation time)