Class InMemoryOutboxStore

java.lang.Object
com.babelqueue.outbox.InMemoryOutboxStore
All Implemented Interfaces:
OutboxStore

public final class InMemoryOutboxStore extends Object implements OutboxStore
Process-local reference OutboxStore backed by a map — for tests and single-process demos. It has no real transaction: save(byte[], String) just appends, so it cannot deliver the atomic-with-the-business-write guarantee a production store gives. Use a database-backed adapter (a JDBC one, binding save to the caller's open transaction) in production.

It still faithfully models the relay contract: rows are pending until markPublished(List), fetchUnpublished(int) returns them oldest-first (a LinkedHashMap preserves insertion order), and markFailed(String, String) bumps the attempt count and stores the last error while leaving the row pending for retry. The body is held (and returned) as a verbatim copy of the bytes it was stored with — never re-encoded.

Not thread-safe; intended for single-threaded tests/demos. It does not implement the claim/lock (FOR UPDATE SKIP LOCKED) that a concurrent production relay needs — that is the adapter's job (ADR-0029 §Scope).

  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    int
    Test/inspection helper: the recorded attempt count for one row (0 if unknown).
    fetchUnpublished(int limit)
    Reserve up to limit rows that are pending publish, oldest first, so a relay can forward them.
    Test/inspection helper: the last recorded error for one row ("" if none).
    void
    markFailed(String id, String error)
    Record a failed publish attempt for one row: increment its attempt counter and store the last error, leaving it pending so a later relay pass retries it (at-least-once).
    void
    Mark the given outbox rows as successfully published (so they are never relayed again).
    int
    Test/inspection helper: the number of rows still pending publish.
    save(byte[] encoded, String queue)
    Persist one encoded envelope into the outbox, within the transaction the caller has already opened around its business write.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • InMemoryOutboxStore

      public InMemoryOutboxStore()
  • Method Details

    • save

      public String save(byte[] encoded, String queue)
      Description copied from interface: OutboxStore
      Persist one encoded envelope into the outbox, within the transaction the caller has already opened around its business write. Returns the new row's outbox id (the store's own primary key — NOT meta.id), which the caller may keep for correlation. The body is stored verbatim; an implementation must not re-encode or mutate it.
      Specified by:
      save in interface OutboxStore
      Parameters:
      encoded - the EnvelopeCodec.encode(com.babelqueue.Envelope) output as UTF-8 bytes
      queue - the logical target queue, captured for the relay
      Returns:
      the outbox row id
    • fetchUnpublished

      public List<OutboxRecord> fetchUnpublished(int limit)
      Description copied from interface: OutboxStore
      Reserve up to limit rows that are pending publish, oldest first, so a relay can forward them. Implementations SHOULD lock/claim the rows they return (e.g. SELECT … FOR UPDATE SKIP LOCKED, or a picked_at claim) so two concurrent relays do not both publish the same row; at-least-once still tolerates a rare double send. That claim/lock is the adapter's responsibility — the in-memory reference does not implement it.
      Specified by:
      fetchUnpublished in interface OutboxStore
      Parameters:
      limit - maximum rows to return (a positive batch size)
      Returns:
      pending rows, oldest first; empty when the outbox is drained
    • markPublished

      public void markPublished(List<String> ids)
      Description copied from interface: OutboxStore
      Mark the given outbox rows as successfully published (so they are never relayed again). Called by the relay only after the transport accepted the message.
      Specified by:
      markPublished in interface OutboxStore
      Parameters:
      ids - outbox row ids previously returned by OutboxStore.fetchUnpublished(int)
    • markFailed

      public void markFailed(String id, String error)
      Description copied from interface: OutboxStore
      Record a failed publish attempt for one row: increment its attempt counter and store the last error, leaving it pending so a later relay pass retries it (at-least-once). A store MAY move a row that exceeds a max-attempts threshold to a terminal/parked state, but that policy is the adapter's, not the core's.
      Specified by:
      markFailed in interface OutboxStore
      Parameters:
      id - the outbox row id
      error - a short, human-readable failure reason (never secrets)
    • pendingCount

      public int pendingCount()
      Test/inspection helper: the number of rows still pending publish.
    • attemptsOf

      public int attemptsOf(String id)
      Test/inspection helper: the recorded attempt count for one row (0 if unknown).
    • lastErrorOf

      public String lastErrorOf(String id)
      Test/inspection helper: the last recorded error for one row ("" if none).