Skip to content

Session-scoped buffers (implements ADR-0014) #56

Description

@tetsuh

Summary

Add a <prefix>/buffers/<sid>/<key> scope: a session-scoped, disk-backed,
pull+push large-value store. One put fans the full payload out to live
subscribers and stores identical bytes for later get. Persistence is per-session
(kDurable / kEphemeral).

References

  • ADR-0014 (session-scoped buffers) — normative
  • docs/02_architecture.md §2 (key space), §4 (StorageNode)
  • docs/03_wire_protocol.md §1 (key space)
  • Related: ADR-0002, ADR-0003

Scope

  1. key.hpp: add KeyKind::Buffer; BuildBufferKey(sid, key); ParseKey
    branch for buffers/<sid>/<key>; validation reuses existing <sid>/<key>
    grammar. No $batch, no snap counterpart.
  2. Config / SessionOptions: BufferPersistence { kDurable, kEphemeral };
    SessionOptions{buffers} per session; Config global default (kDurable).
  3. SessionController: on CreateSession, for kDurable create a per-session
    disk StorageEngine for buffers; on CloseSession, purge/close it (subsequent
    get returns not-found).
  4. StorageNode: routing branch for buffers/**:
    • put → for kDurable, write bytes to the session buffer engine; zenoh fans
      the same bytes to live subscribers. For kEphemeral, no store.
    • get/List → for kDurable, respond from the session buffer engine; for
      kEphemeral, respond empty/not-found.
    • delete → remove from the session buffer engine.
  5. Late-join: document and test the querying-subscriber ordering
    (get buffers/<sid>/**, then subscribe), mirroring ParamCache::Attach.
  6. Docs: apply the patches in doc-patches.md to docs/02 §2 and
    docs/03 §1.

Acceptance criteria (AC)

  • AC1: BuildBufferKey / ParseKey round-trip for valid keys; invalid <sid>
    or <key> rejected; buffers/** never parses as Base/Session/Snapshot.
  • AC2: A put to buffers/<sid>/<key> in a kDurable session is (a) delivered
    in full to a pre-existing subscriber and (b) returned identically by a later
    get. Byte-for-byte equality asserted.
  • AC3: A late-joining querying subscriber receives all values put before it
    attached, with no lost updates under concurrent puts.
  • AC4: In a kEphemeral session, live subscribers receive the payload but get
    returns not-found and nothing is written to disk.
  • AC5: After CloseSession, get on any buffers/<sid>/** key returns
    not-found; the per-session engine's storage is released.
  • AC6: ParamCache subscribed to session/<sid>/** does not receive any
    buffers/<sid>/** payloads (scope isolation test).
  • AC7: A raw zenoh client can put and get a buffer following docs/03 §1
    (interop test), consistent with existing RawZenohClient* tests.

Dependencies

  • Depends on: StorageEngine abstraction (done), StorageNode, SessionController
    (v0.2), and a disk engine for kDurable = RocksDBEngine (v0.4, [M1] RocksDBEngine #8).
  • Not required: snapshots, batch, ack.

Out of scope (follow-ups)

  • Shared-memory zero-copy for same-host transfers.
  • Per-subscriber reliability tuning and backpressure policy.
  • HTTP GET access (covered by the gateway issue / ADR-0015).

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:nodeStorageNode: routing, sessions, batch, acktype:featNew feature or capability

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions