52 lines
2.4 KiB
Java
52 lines
2.4 KiB
Java
package dev.ltms.bridged.msg;
|
|
|
|
import java.util.List;
|
|
|
|
/**
|
|
* Holds terminal worker→primary replies that arrive with no live send to resolve, keyed by worker
|
|
* session (target), until the primary drains them. Soft-state in Stage 1 (in-memory, lost on restart);
|
|
* the Stage 2 AMQP adapter implements the same contract with cross-restart durability.
|
|
*
|
|
* <p><strong>This interface is the port.</strong> {@link InMemoryReplyInbox} is the Stage-1 adapter;
|
|
* an AMQP-backed adapter (Stage 2) must implement the same contract (idempotent publish, FIFO peek,
|
|
* at-least-once ack).
|
|
*
|
|
* <p><strong>Ownership is explicit.</strong> A gateway {@link #own owns} the inbox for each agent it
|
|
* spawned; only the owner consumes and drains it. {@link #publish} sends a reply to the target's
|
|
* inbox but does <em>not</em> imply ownership or start a consumer. This separation is required by
|
|
* CB-308 federation, where one gateway may publish to an agent owned by another gateway.
|
|
*/
|
|
public interface ReplyInbox {
|
|
|
|
/** A queued reply: an idempotency id, the worker session it came from, and the reply text. */
|
|
record InboxMessage(String msgId, String target, String content) {}
|
|
|
|
/**
|
|
* Start owning (consuming) the inbox for {@code target}. Idempotent: multiple calls for the same
|
|
* target are no-ops. The owner is the only gateway that may {@link #peek} and {@link #ack} replies
|
|
* for this target.
|
|
*/
|
|
void own(String target);
|
|
|
|
/**
|
|
* Stop owning (consuming) the inbox for {@code target}. Idempotent. Any replies held locally but
|
|
* not yet acked are dropped from the local snapshot; the underlying durable queue keeps
|
|
* unacked messages for redelivery when the target is re-owned.
|
|
*/
|
|
void release(String target);
|
|
|
|
/**
|
|
* Queue {@code content} from worker {@code target} under {@code msgId}. Idempotent: publishing an
|
|
* already-present {@code msgId} for {@code target} is a no-op (dedup), so an at-least-once Stage-2
|
|
* redelivery cannot double-queue. Publishing does <em>not</em> imply ownership and must not start a
|
|
* consumer.
|
|
*/
|
|
void publish(String target, String msgId, String content);
|
|
|
|
/** Non-destructive snapshot of pending replies for {@code target} (FIFO), empty list if none. */
|
|
List<InboxMessage> peek(String target);
|
|
|
|
/** Remove the reply {@code msgId} for {@code target} once the primary has taken it. No-op if absent. */
|
|
void ack(String target, String msgId);
|
|
}
|