Class InMemorySessionRepository
- All Implemented Interfaces:
SessionRepository
SessionRepository in memory, for tests and demos: the sessions
are lost on restart and not shared across instances. A session and its log are kept
together, and every mutation is one ConcurrentHashMap.compute(K, java.util.function.BiFunction<? super K, ? super V, ? extends V>).- Since:
- 2.1.0
- Author:
- Christian Tzolov
-
Nested Class Summary
Nested Classes -
Method Summary
Modifier and TypeMethodDescriptionvoidappendEvent(SessionEvent event) Appends one event to the log of the session named bySessionEvent.getSessionId().booleanappendEvents(String sessionId, List<SessionEvent> events, long expectedVersion) Appends several events in order, atomically, only if the log's version equalsexpectedVersion; otherwise nothing is written andfalseis returned.builder()Returns a newInMemorySessionRepository.Builder.voidDeletes the session and its events.intdeleteExpiredSessions(Instant before) Deletes every session that expired before the given instant, with their events, in one atomic step per session, so a session whose expiry was extended concurrently (SessionRepository.save(org.springframework.ai.session.Session)) is kept.@Nullable SessionfindByMetadata(String name, String value) findEvents(String sessionId, EventFilter filter) The events of the session the filter selects, oldest first; an empty list for a session that does not exist.longgetEventVersion(String sessionId) The version of the session's log, advanced on everySessionRepository.appendEvent(org.springframework.ai.session.SessionEvent)that appends a new event and on every successfulSessionRepository.appendEvents(java.lang.String, java.util.List<org.springframework.ai.session.SessionEvent>, long);0for a session that does not exist or has no events.Persists session metadata (create or update).booleansaveIfAbsent(Session session) Inserts the session unless one with the same id exists, atomically: a primary-key-guardedINSERT, or a compare-and-set put.
-
Method Details
-
builder
Returns a newInMemorySessionRepository.Builder. -
save
Description copied from interface:SessionRepositoryPersists session metadata (create or update). If the session already exists its event log and its originalSession.createdAt()are preserved; the other metadata fields are replaced.- Specified by:
savein interfaceSessionRepository- Returns:
- the saved session
-
saveIfAbsent
Description copied from interface:SessionRepositoryInserts the session unless one with the same id exists, atomically: a primary-key-guardedINSERT, or a compare-and-set put.SessionService.create(org.springframework.ai.session.CreateSessionRequest)relies on it, so two concurrent creates of one id cannot both succeed.- Specified by:
saveIfAbsentin interfaceSessionRepository- Returns:
trueif the session was inserted,falseif one with the same id exists; the existing session is left untouched
-
findById
- Specified by:
findByIdin interfaceSessionRepository
-
findByMetadata
Description copied from interface:SessionRepositoryThe sessions whosemetadataholdsvalueundername, oldest first (creation time, then id). The one scoped lookup of the store, in the shape of Spring Session'sfindByIndexNameAndIndexValue: the store indexes attributes and has no notion of ownership. Every store indexesSessionAttributes.PRINCIPAL_NAME; a store that cannot index every key documents which others it answers for.- Specified by:
findByMetadatain interfaceSessionRepository- Parameters:
name- the metadata keyvalue- the value, compared as a string
-
deleteExpiredSessions
Description copied from interface:SessionRepositoryDeletes every session that expired before the given instant, with their events, in one atomic step per session, so a session whose expiry was extended concurrently (SessionRepository.save(org.springframework.ai.session.Session)) is kept.- Specified by:
deleteExpiredSessionsin interfaceSessionRepository- Parameters:
before- the expiry cut-off- Returns:
- the number of sessions deleted
-
delete
Description copied from interface:SessionRepositoryDeletes the session and its events.- Specified by:
deletein interfaceSessionRepository
-
appendEvent
Description copied from interface:SessionRepositoryAppends one event to the log of the session named bySessionEvent.getSessionId().Idempotent by id: an event whose id is already in the session's log is a retried append and a no-op, neither a duplicate nor an error, and the version is not advanced. A caller that wants to retry safely supplies its own id rather than the builder's random one. Event ids are unique across sessions: a persistent store keys events by id alone and rejects an id used by another session rather than dropping the event.
- Specified by:
appendEventin interfaceSessionRepository
-
appendEvents
Description copied from interface:SessionRepositoryAppends several events in order, atomically, only if the log's version equalsexpectedVersion; otherwise nothing is written andfalseis returned. On success the version advances once, whatever the number of events. This is how a compaction is recorded: oneEventType.COMPACTIONboundary and its summary events, with the version check keeping two concurrent compactions from both landing. ReadSessionRepository.getEventVersion(java.lang.String)beforeSessionRepository.findEvents(java.lang.String, org.springframework.ai.session.EventFilter), then pass that version here.- Specified by:
appendEventsin interfaceSessionRepository- Parameters:
sessionId- the session whose log is appended to; every event must belong to itevents- the events, in order; at least one, with ids that are new to the logexpectedVersion- the version the caller read- Returns:
truewhen the events were appended,falsewhen the version did not match
-
getEventVersion
Description copied from interface:SessionRepositoryThe version of the session's log, advanced on everySessionRepository.appendEvent(org.springframework.ai.session.SessionEvent)that appends a new event and on every successfulSessionRepository.appendEvents(java.lang.String, java.util.List<org.springframework.ai.session.SessionEvent>, long);0for a session that does not exist or has no events. Read it beforeSessionRepository.findEvents(java.lang.String, org.springframework.ai.session.EventFilter), so that the version passed toSessionRepository.appendEvents(java.lang.String, java.util.List<org.springframework.ai.session.SessionEvent>, long)is not newer than the events read.- Specified by:
getEventVersionin interfaceSessionRepository
-
findEvents
Description copied from interface:SessionRepositoryThe events of the session the filter selects, oldest first; an empty list for a session that does not exist.A
EventFilter.Window.Lastwindow returns the newest N matching events, extended back to the start of the turn it lands in (the nearest precedingturn startamong the matches), so a tool call is never returned without its results; the extension is skipped when no turn start precedes the window. WithEventFilter.activeView()the filter applies to the active view, the events the newestEventType.COMPACTIONboundary names and everything appended after it, rather than to the whole log.EventFilter.apply(List)is the reference implementation of both. A store pushes the criteria and the window down to its query, so that a read does not cost the whole log, and may fetch only the rows a view can contain and hand them toapply, asJdbcSessionRepositorydoes.- Specified by:
findEventsin interfaceSessionRepository
-