Package at.aimon.session.web
Class LocalSessionCache
java.lang.Object
at.aimon.session.web.LocalSessionCache
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.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final classLive entry held by the cache: exposes theAgentSessionand ensures idempotent close. -
Constructor Summary
ConstructorsConstructorDescriptionLocalSessionCache(AgentSessionOpener opener, Duration idleTtl, int maxEntries) LocalSessionCache(AgentSessionOpener opener, Duration idleTtl, int maxEntries, com.github.benmanes.caffeine.cache.Ticker ticker) LocalSessionCache(AgentSessionOpener opener, Duration idleTtl, int maxEntries, com.github.benmanes.caffeine.cache.Ticker ticker, SessionMetrics metrics) -
Method Summary
Modifier and TypeMethodDescriptionvoidcloseAll()Drop and close every cached entry.ensureOpen(at.aimon.core.agent.conversation.ConversationId id, at.aimon.core.agent.AgentExecutionContextId contextId, at.aimon.core.agent.session.AgentSessionOptions options) Convenience overload — equivalent toensureOpen(ConversationId, AgentExecutionContextId, AgentSessionOptions, OpenAttributes)withOpenAttributes.empty().ensureOpen(at.aimon.core.agent.conversation.ConversationId id, at.aimon.core.agent.AgentExecutionContextId contextId, at.aimon.core.agent.session.AgentSessionOptions options, at.aimon.core.agent.session.OpenAttributes openAttributes) Lazily opens a session foridvia the injected factory, or returns the cached entry on hit.voidevict(at.aimon.core.agent.conversation.ConversationId id) Drop and close the entry forid, if any.voidforEachSession(Consumer<at.aimon.core.agent.session.AgentSession> action) Applyactionto every currently cached session.peek(at.aimon.core.agent.conversation.ConversationId id) Returns the cached entry forid, if any.voidsweep()Force a synchronous cleanup pass — runs Caffeine's lazy maintenance, including TTL-based eviction.
-
Constructor Details
-
LocalSessionCache
-
LocalSessionCache
public LocalSessionCache(AgentSessionOpener opener, Duration idleTtl, int maxEntries, com.github.benmanes.caffeine.cache.Ticker ticker) -
LocalSessionCache
public LocalSessionCache(AgentSessionOpener opener, Duration idleTtl, int maxEntries, com.github.benmanes.caffeine.cache.Ticker ticker, SessionMetrics metrics)
-
-
Method Details
-
ensureOpen
public LocalSessionCache.SessionEntry ensureOpen(at.aimon.core.agent.conversation.ConversationId id, at.aimon.core.agent.AgentExecutionContextId contextId, at.aimon.core.agent.session.AgentSessionOptions options) Convenience overload — equivalent toensureOpen(ConversationId, AgentExecutionContextId, AgentSessionOptions, OpenAttributes)withOpenAttributes.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)contextId- the agent-scoped execution context id 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, at.aimon.core.agent.AgentExecutionContextId contextId, at.aimon.core.agent.session.AgentSessionOptions options, at.aimon.core.agent.session.OpenAttributes openAttributes) Lazily opens a session foridvia the injected factory, or returns the cached entry on hit.openAttributesare forwarded to the opener only on cache miss; subsequentensureOpencalls for the sameidreuse the cached session and ignore any attributes supplied at hit time. This matches the documentedOpenAttributescontract.- Parameters:
id- the conversation (must not be null)contextId- the agent-scoped execution context id to bind on first open (must not be null)options- session options (must not be null)openAttributes- caller-provided open attributes; passOpenAttributes.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 forid, 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 forid, if any.- Parameters:
id- the conversation (must not be null)
-
closeAll
public void closeAll()Drop and close every cached entry. -
forEachSession
Applyactionto 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 periodicScheduledExecutorServicetask.
-