Skip to content

RcMap: Support updating idleTimeToLive when re-acquiring with longer TTL #5882

@IGassmann

Description

@IGassmann

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 livestorejs/livestore#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

  1. Entry TTL update: When re-acquiring, compare the requested TTL with entry.idleTimeToLive and update if larger
  2. Expiration recalculation: If entry.expiresAt is set (resource is idle with pending disposal), extend it proportionally
  3. Touch behavior: touch should continue using the (potentially updated) entry.idleTimeToLive
  4. Thread safety: TTL updates must be atomic with respect to the release/expiration logic

Related Issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions