Class LocalSessionCache

java.lang.Object
at.aimon.session.web.LocalSessionCache

public final class LocalSessionCache extends Object
Per-node, per-conversation session cache backed by Caffeine.

Applies two simultaneous caps per design §5.2:

  • idleTtl — idle-after-access TTL ensures heavy session-scoped resources (MCP connections, knowledge stores) do not linger indefinitely.
  • maxEntries — LRU bound prevents one-off conversation bursts from exhausting heap.

Caffeine has no background sweeper; TTL eviction is lazy. Callers must invoke sweep() periodically (the manager runs a ScheduledExecutorService to do this) to ensure idle entries' close listeners fire promptly.

The cache is thread-safe; LocalSessionCache.SessionEntry.closeQuietly() uses an AtomicBoolean to guarantee single-close even when a sweeper and an explicit closeAll() race.

  • Constructor Details

  • Method Details

    • ensureOpen

      public LocalSessionCache.SessionEntry ensureOpen(at.aimon.core.agent.conversation.ConversationId id, String agentRef, at.aimon.core.agent.session.AgentSessionOptions options)
      Convenience overload — equivalent to ensureOpen(ConversationId, String, AgentSessionOptions, OpenAttributes) with OpenAttributes.empty(). Tests and simple internal callers that do not surface caller-domain attributes can use this form unchanged.
      Parameters:
      id - the conversation (must not be null)
      agentRef - the agent name to bind on first open (must not be null)
      options - session options (must not be null)
      Returns:
      the live session entry (never null)
    • ensureOpen

      public LocalSessionCache.SessionEntry ensureOpen(at.aimon.core.agent.conversation.ConversationId id, String agentRef, at.aimon.core.agent.session.AgentSessionOptions options, at.aimon.core.agent.session.OpenAttributes openAttributes)
      Lazily opens a session for id via the injected factory, or returns the cached entry on hit.

      openAttributes are forwarded to the opener only on cache miss; subsequent ensureOpen calls for the same id reuse the cached session and ignore any attributes supplied at hit time. This matches the documented OpenAttributes contract.

      Parameters:
      id - the conversation (must not be null)
      agentRef - the agent name to bind on first open (must not be null)
      options - session options (must not be null)
      openAttributes - caller-provided open attributes; pass OpenAttributes.empty() when none (must not be null)
      Returns:
      the live session entry (never null)
    • peek

      public Optional<LocalSessionCache.SessionEntry> peek(at.aimon.core.agent.conversation.ConversationId id)
      Returns the cached entry for id, if any. Does not refresh the access timestamp on miss.
      Parameters:
      id - the conversation (must not be null)
      Returns:
      the cached entry, or empty
    • evict

      public void evict(at.aimon.core.agent.conversation.ConversationId id)
      Drop and close the entry for id, if any.
      Parameters:
      id - the conversation (must not be null)
    • closeAll

      public void closeAll()
      Drop and close every cached entry.
    • forEachSession

      public void forEachSession(Consumer<at.aimon.core.agent.session.AgentSession> action)
      Apply action to every currently cached session. Used by the manager during graceful shutdown to trip every active turn. The visitor must not throw.
      Parameters:
      action - the visitor (must not be null)
    • sweep

      public void sweep()
      Force a synchronous cleanup pass — runs Caffeine's lazy maintenance, including TTL-based eviction. The manager runs this from a periodic ScheduledExecutorService task.