Exchange

Bidirectional signal flow. Request/response patterns. The signal goes out, the answer comes back. The wire remembers where the signal came from. respond() routes back to the source.

The Exchange Operator

The <-> operator creates a bidirectional wire. Unlike the unidirectional ->, exchange allows signals to flow in both directions through the same connection.

.zpexchange operator
// HTTP: request flows through gates, response returns
request <-> { gate(path: "/api") -> handler } -> response

Request/Response

.zprequest response
// message queue: consumer receives, ack flows back
message <-> consumer -> ack -> advance(offset)

// shorthand: respond() sends back through originating wire
request -> handler -> respond(200, data)

HTTP Server

A complete HTTP server in Z+. Signal sources, routing gates, and response — all in wiring.

.zphttp server
// signal source
server : net.listen(port: 8080) -> requests

// route by path — each gate filters, handler responds
requests -> gate(path: "/api") -> handler -> respond
requests -> gate(path: "/") -> static -> respond

// telemetry taps
requests ~> rate(per: 1s) ~> rps
requests ~> gate(status: 5xx) ~> count(per: 1h) ~> error_rate

Acknowledge Pattern

For reliable message processing: receive a message, process it, then send an acknowledgment back through the originating wire to advance the consumer offset.

.zpacknowledge
// reliable processing with ack
channel("orders") <-> consumer -> {
    process -> respond(ack),
    on_fail -> respond(nack) -> retry
}

// the ack flows back through the exchange
// advancing the consumer's position in the channel

Bidirectional Device Communication

.zpdevice exchange
// sensor with command feedback
sensor <-> controller
// controller sends commands to sensor
// sensor sends readings to controller
// same wire, both directions

// network discovery with response
net.discover(proto: modbus) <-> devices
// discovery request goes out
// device responses come back
// all through the same exchange