Class InMemorySessionStore<S>
- Type Parameters:
S- the type of custom session state
- All Implemented Interfaces:
SessionStore<S>,SnapshotReader<S>,SnapshotSubscriber,SnapshotWriter<S>
SessionStore and SnapshotSubscriber.
Used by conformance tests and as the simplest full implementation of the saveSnapshot
read-modify-write contract.
Deep-copy strategy
Snapshots are deep-copied on both write (store) and read (return) using a JSON round-trip via
the shared ObjectMapper (valueToTree → treeToValue(node,
SessionSnapshot.class)). Because of Java's type erasure, the round-trip uses the raw type
SessionSnapshot (without the <S> parameter), so the custom field of SessionState will be deserialized as a LinkedHashMap rather than as S.
This is acceptable for the in-memory store used dynamically (conformance tests use
Map<String,Object> state).
Subscriber notification
Callbacks are collected under the lock and invoked after releasing the lock to prevent deadlock if a callback re-enters the store (e.g. to read the new snapshot).
Subscriber semantics (Go-compatible)
If the snapshot is already present when onSnapshotStateChange(java.lang.String, java.util.function.Consumer<com.google.genkit.ai.agent.SessionSnapshot<?>>, com.google.genkit.ai.agent.SessionStoreOptions) is called, the callback
is not invoked immediately. The callback fires only when a subsequent saveSnapshot(java.lang.String, com.google.genkit.ai.agent.SnapshotMutator<S>, com.google.genkit.ai.agent.SessionStoreOptions) causes a status change (including the first save when existing is null).
-
Constructor Summary
ConstructorsConstructorDescriptionCreates a newInMemorySessionStorewithrejectBranchingdefaulting to false.InMemorySessionStore(boolean rejectBranchingSessions) Creates a newInMemorySessionStore. -
Method Summary
Modifier and TypeMethodDescriptionRetrieves a session snapshot.onSnapshotStateChange(String snapshotId, Consumer<SessionSnapshot<?>> cb, SessionStoreOptions options) Subscribes to status changes for the snapshot identified bysnapshotId.saveSnapshot(String snapshotId, SnapshotMutator<S> mutator, SessionStoreOptions options) Atomically reads the snapshot identified bysnapshotId(or creates a new one), appliesmutator, and persists the result.
-
Constructor Details
-
InMemorySessionStore
public InMemorySessionStore()Creates a newInMemorySessionStorewithrejectBranchingdefaulting to false. -
InMemorySessionStore
public InMemorySessionStore(boolean rejectBranchingSessions) Creates a newInMemorySessionStore.- Parameters:
rejectBranchingSessions- iftrue,LeafSelection.selectLeaf(java.util.List<com.google.genkit.ai.agent.SessionSnapshot<S>>, boolean)will throw when more than one leaf is detected for a session
-
-
Method Details
-
getSnapshot
Retrieves a session snapshot.When
GetSnapshotOptions.getSnapshotId()is set the store returns that specific snapshot. WhenGetSnapshotOptions.getSessionId()is set the store resolves and returns the latest leaf snapshot for that session. Returnsnullif no matching snapshot exists.When
GetSnapshotOptions.getSnapshotId()is set, returns a deep copy of the stored snapshot (ornullif absent). WhenGetSnapshotOptions.getSessionId()is set, gathers all snapshots whosesessionIdequals it, appliesLeafSelection, and returns a deep copy of the result. If neither id is set, returnsnull.- Specified by:
getSnapshotin interfaceSnapshotReader<S>- Parameters:
opts- options specifying which snapshot to retrieve; exactly one ofsnapshotId/sessionIdmust be set- Returns:
- the matching snapshot, or
nullif none exists
-
saveSnapshot
public String saveSnapshot(String snapshotId, SnapshotMutator<S> mutator, SessionStoreOptions options) Atomically reads the snapshot identified bysnapshotId(or creates a new one), appliesmutator, and persists the result.Implements the full saveSnapshot contract:
- Under lock: read existing snapshot (deep copy) identified by
snapshotId. - Invoke
mutator.apply(existing); if result isnull, returnnull(no write). - Determine final id:
snapshotId != null ? snapshotId : (result.snapshotId != null ? result.snapshotId : UUID.randomUUID()). Forceresult.snapshotId = finalId. - Preserve sessionId from existing snapshot when updating.
- Validate sessionId is non-null and non-empty; throw
GenkitExceptionwithINVALID_ARGUMENTotherwise. - Default
nullstatus toSnapshotStatus.COMPLETED. - Store deep copy. Collect subscriber callbacks if status changed (existing was null or status differs).
- Invoke collected callbacks after releasing the lock.
- Specified by:
saveSnapshotin interfaceSnapshotWriter<S>- Parameters:
snapshotId- the ID of the snapshot to write; ifnullthe store mints a UUIDmutator- the pure read-modify-write function; receives the existing snapshot (ornull) and returns the snapshot to persist, ornullto declineoptions- store options- Returns:
- the snapshot ID that was written, or
nullif the mutator declined
- Under lock: read existing snapshot (deep copy) identified by
-
onSnapshotStateChange
public AutoCloseable onSnapshotStateChange(String snapshotId, Consumer<SessionSnapshot<?>> cb, SessionStoreOptions options) Subscribes to status changes for the snapshot identified bysnapshotId.Invokes
cbimmediately with the current snapshot and again on every subsequent change. The returnedAutoCloseableunsubscribes when closed.Registers
cbto be invoked on subsequent status changes forsnapshotId. If the snapshot already exists, the callback is invoked immediately with a deep copy of the current snapshot (before returning). The callback will also fire on any subsequent status changes. If the snapshot does not currently exist, the callback is registered and will fire on the first save (status change from null). Returns anAutoCloseablethat unregisters the callback.- Specified by:
onSnapshotStateChangein interfaceSnapshotSubscriber- Parameters:
snapshotId- the snapshot to observecb- callback invoked with the updated snapshot on each changeoptions- store options- Returns:
- a handle that cancels the subscription when
AutoCloseable.close()is called
-