All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- BREAKING (session on-disk layout).
AerospikeSessionServiceevent history now lives in append-only segment records (app:user:session:g:NNNNNNNN), each a single K_ORDEREDeventsMap keyed"{ts_micros:020d}:{event_id}". This replaces the previous hot-tail-on-the-session-record plus sealed-c:chunk-record model. Sessions written by<= 0.0.2are not read by this version (clean break, no migrator). - Event history now orders by
event.timestamp(the map key), not by insertion order. Identical for monotonic timestamps; events sharing a microsecond are tie-broken byevent_id.
- Idempotent
append_event: the segment-map key is a pure function of(event.id, event.timestamp), so a retried/duplicated append overwrites the same slot and can never duplicate an event in history. - Overflow-driven segment rollover: a real
RecordTooBigis the only rollover trigger (no client-side byte estimation/thresholds).curis advanced with acur == Nguarded increment so concurrent rollovers converge. - Single-RTT append hot path: a no-state-delta append is one
operate; an append carrying state is onebatch_writecoalescing the segment write with the session/app/user state writes (multi-scope appends now match single-scope latency instead of issuing up to three sequential operates). - Bounded retry on transient write back-pressure: the (now-idempotent) append hot path retries
DeviceOverloadand ambiguousTimeoutErrorwith jittered backoff, including per-recordDeviceOverloadin the coalescedbatch_write.create_sessionretriesDeviceOverloadonly (aPOLICY_EXISTS_CREATEput is not timeout-idempotent).
- Heavy-concurrency data loss / unrecoverable
RecordTooBigon a single hot session: large concurrent appends previously overran the 1 MiB write-block-size and dropped events. Segments now pack tomax-record-sizeand roll over with no loss and no duplication. - A lone event exceeding
max-record-sizenow raises a clearRecordTooBiginstead of looping (object-store spill remains future work).
flush_threshold_bytes,huge_event_bytes,max_tail_bytesconstructor params;codec.estimate_event_size;keys.chunk_key; thetbytes/chunks/seqsession bins and thets_lo/ts_hi/cidxchunk bins.- Drop
[benchmark]optional extra from PyPI metadata; usebenchmarks/requirements.txtinstead (PyPI rejects VCS direct dependencies).
0.0.2 - 2026-05-28
- Per-user session manifest (
app:user:sl) and bin-projectedlist_sessions(app, user)metadata reads. - Posting-list inverted index for lexical memory search (
app:user:kw:<token>primary keys). - Data-model diagrams and updated
docs/data-model.md(manifests, posting rows, artifact head records). - Ecosystem benchmarks:
--backend redis,--results-dir,paired_*profiles; deps inbenchmarks/requirements.txt(google-adk-extras,redis,sqlalchemy). benchmarks/workloads/_redis_backend.pyandredis_*methods on ecosystem workloads for cross-backend comparison viagoogle-adk-extras.AerospikeMemoryService.add_events_to_memory(incremental event ingest with dedupe by event id).- Upstream ADK contract tests ported from
google/adk-pythonfor sessions, artifacts, and memory.
AerospikeMemoryService.search_memoryuses posting-listbatch_readper query token (no list-element secondary index onkeywords).AerospikeSessionService.list_sessionswithuser_idreads the session manifest instead of scanningidx_*_sess_uid.- Inline event codec bumped to v2: full
Event.model_dumpstored underpayloadfor lossless round-trip (v0/v1 records remain readable).
- Concurrent
save_artifactcalls allocate distinct versions via atomicoperateon a per-file head record (:__head__).
0.0.1 - 2026-05-27
- Initial PyPI release.
AerospikeSessionService,AerospikeArtifactService, andAerospikeMemoryServicefor Google ADK 2.x.aerospike://URI support viaadk_aerospike.register().- Chunked session records, server-side lexical memory search, and composite tenant indexes.