feat: producer-listen — listen establisher (shape 2) + AcceptQueue contract
- AcceptFn: the injected accepted-connection source (the assembly layer owns the listener + accept loop; the protocol never binds — OQ-TN-04). - AcceptQueue: the protocol-side queue contract (async push/pop/ close; FIFO always-before-take ordering; close-while-waiting resolves None). Empty-queue posture is assembly-owned (a late accept is legitimate; resource_shortage is the closure's mapping; the wrapper's 10s establishment timeout is the backstop). - listen_establisher: same open op, same params, same typed errors — registry namespace gate → accept() → Establishment::new(plan); the pump handler is untouched (plan-flow with a different source). - register_tunnel_listen_openable: same spec/pump registration with the listen establisher (the honest shape vs a dial/accept enum: the establisher is the only difference; one establisher per op id per session registry — documented). - Tests (tests/producer_listen.rs, 6): listen flow end-to-end, FIFO ordering across two opens (R-01 plan-flow, listen-flavored), empty queue -> resource_shortage, closed listener -> dial_failed, unknown resource -> unknown_resource, late-push wait-then-resolve. - Harness: RegistrationMode enum + wire_listen. - TargetHandle gains a structural Debug impl (test ergonomics). Verified: cargo test green (44), clippy -D warnings (native + wasm32), fmt clean, wasm32 check passes.
This commit is contained in:
+49
-11
@@ -92,9 +92,16 @@ pub struct Topology {
|
||||
/// `serving_identity` is the explicit `ServingConfig.identity`
|
||||
/// override (CF-005 remediation (a)) — `None` in the primary path.
|
||||
/// `provider` resolves payload tokens (the hub-forwarding path).
|
||||
/// The open-op registration mode: a dial establisher (shape 1) or a
|
||||
/// listen establisher over an assembly-fed [`AcceptQueue`] (shape 2).
|
||||
pub enum RegistrationMode {
|
||||
Dial(alktunnels::producer::DialFn),
|
||||
Listen(alktunnels::producer::AcceptFn),
|
||||
}
|
||||
|
||||
pub async fn wire_with(
|
||||
registry: ResourceRegistry,
|
||||
dial: alktunnels::producer::DialFn,
|
||||
mode: RegistrationMode,
|
||||
transport_identity: Option<Identity>,
|
||||
serving_identity: Option<Identity>,
|
||||
provider: Arc<dyn IdentityProvider>,
|
||||
@@ -185,15 +192,29 @@ pub async fn wire_with(
|
||||
producer_client.manager().clone(),
|
||||
alkcall::channels::policy::default_policy(),
|
||||
);
|
||||
register_tunnel_openable(
|
||||
&core,
|
||||
®istry,
|
||||
&producer_op_registry,
|
||||
AuthContext::anonymous(b"alk/tunnel"),
|
||||
dial,
|
||||
Some(Arc::clone(&identity_witness)),
|
||||
)
|
||||
.expect("register tunnel openable");
|
||||
match mode {
|
||||
RegistrationMode::Dial(dial) => {
|
||||
register_tunnel_openable(
|
||||
&core,
|
||||
®istry,
|
||||
&producer_op_registry,
|
||||
AuthContext::anonymous(b"alk/tunnel"),
|
||||
dial,
|
||||
Some(Arc::clone(&identity_witness)),
|
||||
)
|
||||
.expect("register tunnel openable");
|
||||
}
|
||||
RegistrationMode::Listen(accept) => {
|
||||
alktunnels::producer::register_tunnel_listen_openable(
|
||||
&core,
|
||||
®istry,
|
||||
&producer_op_registry,
|
||||
AuthContext::anonymous(b"alk/tunnel"),
|
||||
accept,
|
||||
)
|
||||
.expect("register tunnel listen openable");
|
||||
}
|
||||
}
|
||||
let producer_client = Arc::new(producer_client);
|
||||
|
||||
// --- consumer pieces (captured from the hook) -------------------------
|
||||
@@ -215,7 +236,24 @@ pub async fn wire_with(
|
||||
pub async fn wire(registry: ResourceRegistry, dial: alktunnels::producer::DialFn) -> Topology {
|
||||
wire_with(
|
||||
registry,
|
||||
dial,
|
||||
RegistrationMode::Dial(dial),
|
||||
Some(consumer_identity()),
|
||||
None,
|
||||
Arc::new(alkcall::core::auth::NoopIdentityProvider),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// The listen topology (shape 2): the producer's establisher pops
|
||||
/// accepted handles from the assembly-fed [`AcceptQueue`] instead of
|
||||
/// dialing. Same identity posture as [`wire`].
|
||||
pub async fn wire_listen(
|
||||
registry: ResourceRegistry,
|
||||
accept: alktunnels::producer::AcceptFn,
|
||||
) -> Topology {
|
||||
wire_with(
|
||||
registry,
|
||||
RegistrationMode::Listen(accept),
|
||||
Some(consumer_identity()),
|
||||
None,
|
||||
Arc::new(alkcall::core::auth::NoopIdentityProvider),
|
||||
|
||||
Reference in New Issue
Block a user