Repository navigation
3.2 ZmqIpcBackend
Feature-gated (zmq) IpcBackend that subscribes to a remote compute PUB socket and returns the latest valid float readout on each process_batch. Implementation: src/zmq_backend.rs. Shared parser: src/zmq_readout.rs. Deprecated alias: ZmqRuntimeBackend.
Does not implement HybridFlowBackend. Structured IpcMessage PUB/SUB lives in zmq_message (ZmqHybridFlowBackend) as of 08d2f28 / #55.
libzmq sockets are Send + !Sync. ZmqIpcBackend stores the socket in Mutex<Option<ExclusiveSocket>> so the public type is Send + Sync without unsafe impl Sync on zmq::Socket. initialize / process_batch / reset take &mut self for the readout cache; save_state / get_spike_states take &self and do not touch the socket.
Since #62, ZmqIpcBackend::new() takes its context from the crate-private shared_context() instead of zmq::Context::new(). Every socket in the crate shares one process-wide libzmq context, held in a OnceLock until process exit, because libzmq 4.3.4 segfaults in its command mailbox when several contexts call zmq_connect concurrently. Sockets still have a single owner. The Linux build.rs API lock that #62 added was removed in #65 because it never reached downstream binaries (7.1); the crate ships no libzmq patch.
On initialize:
- Endpoint from
CORPUS_IPC_ZMQ_READOUT_IPC, elseipc:///tmp/corpus_ipc_readout.ipc. - Create SUB,
set_subscribe(b""),set_rcvhwm(16). - Set
ZMQ_RECONNECT_IVL/ZMQ_RECONNECT_IVL_MAXbeforeconnect(defaults 100 ms / 5000 ms; override withCORPUS_IPC_ZMQ_RECONNECT_IVL_MS/CORPUS_IPC_ZMQ_RECONNECT_IVL_MAX_MS, positive ms only). - Store under the mutex. Idempotent after success until
reset.
Publisher late-start / stop / restart at the same endpoint is handled by libzmq's reconnect state machine (subscribe filter is re-sent). There is no crate-owned retry thread. reset + initialize remains the path for switching endpoints.
Constants: RECEIVE_DRAIN_MAX_MESSAGES = 64, RECEIVE_DRAIN_MAX_DURATION = 5 ms, READOUT_RCVHWM = 16.
sequenceDiagram
participant Caller
participant ZB as "ZmqIpcBackend"
participant Sock as "SUB socket"
Caller->>ZB: process_batch
loop until EAGAIN or 64 msgs or 5 ms
ZB->>Sock: recv_bytes DONTWAIT
alt Ok bytes
Sock-->>ZB: frame
ZB->>ZB: parse_readout_packet
Note over ZB: prior valid frame increments skipped_readouts
else EAGAIN
Sock-->>ZB: EAGAIN
Note over ZB: stop drain, return newest or cache
else malformed or over cap
Sock-->>ZB: bad frame
ZB-->>Caller: BackendError fail-closed
end
end
ZB-->>Caller: Ok Vec of f32
- A newer valid frame supersedes the previous;
skipped_readouts()counts valid frames dropped by this policy (not silent libzmq HWM drops). -
EAGAINwith an empty drain returns the cachedlast_readoutwithout error. - Malformed or over-limit frames return
BackendErrorand do not update the cache (malformed_readoutsincrements on parse failure).
| Bytes | Field |
|---|---|
0..8 |
tick i64 LE |
8.. |
N × f32 LE |
An 88-byte frame is tick + 20 floats. Length alone cannot distinguish that from a historical 16-readout + 4-modulator layout; this backend does not infer or strip neuromodulator scores. Cap: default 1024 floats (CORPUS_IPC_ZMQ_MAX_READOUT_FLOATS). See 3.3.
reset clears cache/tick/counters and drops the socket under the mutex (zmq_close, default linger). Drop closes through exclusive ownership. After reset, callers must initialize again before process_batch.
- Home
- 1. Overview
- 1.1. Getting Started
- 1.2. Architecture Overview
- 1.3. Crate Exports and Module Map
- 2. Core Abstractions
- 2.1. IpcBackend Trait
- 2.2. HybridFlowBackend Trait
- 2.3. BackendFactory and BackendType
- 2.4. Error Handling
- 3. Backend Implementations
- 3.1. RustBackend
- 3.2. ZmqIpcBackend
- 3.3. ZMQ Readout Parsing and Golden Frames
- 3.4. Structured ZeroMQ IpcMessage Transport
- 4. IPC Protocol and Data Models
- 4.1. IpcMessage Protocol
- 4.2. Batch Data Types
- 4.3. NeuromodulatorSnapshot and Neuromodulator Packet
- 4.4. StimulusBatch and Runtime Ingress
- 4.5. Deserialization Hooks and Model Compat Aliases
- 5. Validation and Wire Compatibility
- 5.1. Validation Framework and ProtocolLimits
- 5.2. ValidationError and ValidationKind
- 5.3. WireCompatibility and Envelope Decoding
- 5.4. Canonical Wire-v1 Encoding
- 6. corpus_ipc_server HTTP Server
- 6.1. REST API Endpoints
- 6.2. Server Configuration and Deployment
- 7. Build, Dependencies, and Quality Gates
- 7.1. Cargo Features and Dependency Isolation
- 7.2. Testing Strategy
- 7.2.1. Wire-v1 Golden Test Vectors
- 7.2.2. Property-Based Wire Tests
- 7.3. CI, Coverage, and Release Qualification
- 8. Project History and Licensing
- 8.1. Naming History and Completed Renames
- 8.2. Licensing
- 9. Glossary