Skip to content

[Architecture Review] State store durability: restart / multi-instance / fencing / cross-store failure tests #5339

Closed

Description

@qqeasonchen

Part of #5296 (Architecture Review).

Q3 from the 2026-09-07 review questions: does each state-store contract have the intended durable implementation, and are restart, multi-instance, fencing, and cross-store failure scenarios covered by executable tests rather than documentation only?

Context

The unified state control plane landed in #5301 Sub-PR A / B / C / D:

Store Interface Backends Where it lives
OffsetStore L1 local RocksDB + LRU runtime
SubscriptionStore L2 cluster-shared Meta prefix-watch + local cache runtime
SessionStore L2 cluster-shared Meta + local cache runtime
DeliveryStateStore L1 (with sub-second flush) RocksDB runtime
DeadLetterStore L3 durable Meta CAS + epoch runtime
TaskStore L3 durable Meta CAS + epoch a2a

What needs verification (Q3 specifics)

For each store:

  1. Durable implementation is the one documented in the contract (not an InMemory* stub in production code).
  2. Restart scenario — kill the runtime, restart, confirm state is recovered and behavior matches pre-crash.
  3. Multi-instance scenario — two runtime instances sharing the same Meta / RocksDB; confirm the store handles concurrent writers (CAS retry, epoch fencing).
  4. Fencing scenario — stale partition owner (pre-[Architecture Review][P0] PARTITION_OWNED_PULL delivery topology (reopens #5300 second mode) #5309) tries to write; confirm the write is rejected (not silently overwritten).
  5. Cross-store failure — one store's backend (Meta) goes down; the runtime either fails fast or degrades gracefully, with the failure visible in metrics / logs.

Specific test scenarios needed (executable, not doc-only)

  • OffsetStore restart: persist offset 100, kill runtime, restart, read offset = 100.
  • SubscriptionStore multi-instance: two instances concurrently register / unregister the same subscription; CAS retry should converge.
  • SessionStore fencing: instance A registers agent X, then is paused; instance B takes over; A's subsequent writes for X are rejected.
  • DeadLetterStore restart: produce an event that fails 3 times, kill runtime, restart, confirm the event is in DLQ (not lost).
  • TaskStore cross-store failure: Meta goes down mid-submit; the TaskStore surfaces the failure rather than silently dropping the task.
  • DeliveryStateStore flush: sub-second flush path; confirm the state survives a kill -9.

Acceptance

  • For each of the 6 stores above, a JUnit/Testcontainers test exists in eventmesh-runtime and passes in CI.
  • The test for each scenario above (restart / multi-instance / fencing / cross-store failure) is referenced in this issue's evidence table.
  • Any store still backed by an InMemory* implementation in production code is either replaced or marked as experimental with a deprecation comment.
  • A state-store-failure-matrix.md (or section in docs/) documents the expected failure mode per backend (Meta, RocksDB).

Depends on / Blocks

Activity

  1. added
    discussionThis issue requires further discussion
    improvementImprove the mechanism or performance
    on Sep 7, 2026
  2. added 2 commits that reference this issue on Sep 8, 2026
  3. added 2 commits that reference this issue on Sep 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    discussionThis issue requires further discussionimprovementImprove the mechanism or performance

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions