Class FileSessionStore<S>
- Type Parameters:
S- the type of custom session state
- All Implemented Interfaces:
SessionStore<S>,SnapshotReader<S>,SnapshotSubscriber,SnapshotWriter<S>
SessionStore and SnapshotSubscriber.
On-disk layout
<dir>/<prefix>/<snapshotId>.json one snapshot per file
<dir>/<prefix>/.pointers/<sessionId>.json pointer: { currentSnapshotId, currentCreatedAt, updatedAt }
The default prefix is "global".
Atomic writes
Each write goes to a .tmp file first, then is renamed to the target path using StandardCopyOption.ATOMIC_MOVE (falling back to StandardCopyOption.REPLACE_EXISTING if
the filesystem does not support atomic moves). This ensures no partial JSON files are visible.
Subscriber / polling
Subscriptions use polling (a shared daemon ScheduledExecutorService) rather than
WatchService. This is simpler and more reliable across platforms (particularly macOS
where WatchService uses polling internally anyway). The poll interval defaults to 2000 ms
and can be overridden via the builder for fast-iteration tests.
De-duplication is done by comparing the serialised content of the snapshot file on each poll tick; the callback fires only when the content has changed.
-
Nested Class Summary
Nested Classes -
Constructor Summary
ConstructorsConstructorDescriptionFileSessionStore(String dir) Creates a newFileSessionStorewith default options (prefix ="global", no chain pruning, polling every 2000 ms). -
Method Summary
Modifier and TypeMethodDescriptionstatic <S> FileSessionStore.Builder<S> Creates a builder forFileSessionStore.Retrieves 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
-
FileSessionStore
Creates a newFileSessionStorewith default options (prefix ="global", no chain pruning, polling every 2000 ms).- Parameters:
dir- the root directory for persisted snapshots; created if absent
-
-
Method Details
-
builder
Creates a builder forFileSessionStore.- Type Parameters:
S- the type of custom session state- Parameters:
dir- the root directory for persisted snapshots- Returns:
- a new builder
-
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, reads<prefix>/<id>.jsonand deserialises it (or returnsnullif absent). WhenGetSnapshotOptions.getSessionId()is set, tries the pointer first; falls back to scanning all*.jsonfiles in the prefix dir (skipping.pointers/), runsLeafSelection, rewrites the pointer, and returns the leaf.- 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 (mirrors
InMemorySessionStore), but persists to disk:- Validate path safety for
snapshotId(if non-null). - Under lock: read existing snapshot file.
- Apply mutator; if result is
null, returnnull(no write). - Determine final id; apply sessionId / status defaulting.
- Atomic write to
<prefix>/<finalId>.json. - Advance pointer if this is a new snapshot row.
- Prune chain if
maxPersistedChainLength > 0. - Notify subscribers if status changed.
- 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
- Validate path safety for
-
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 a polling subscription for the snapshot identified by
snapshotId. If the snapshot file already exists, the callback is fired immediately with the current content. A shared daemonScheduledExecutorServicepolls the file everysnapshotWatchPollIntervalMsmilliseconds; the callback fires when the serialised content changes. CallingAutoCloseable.close()on the returned handle cancels the poll.- 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
-