Repository navigation
4.1 IpcMessage Protocol
Relevant source files
The following files were used as context for generating this wiki page:
The IpcMessage protocol serves as the top-level Inter-Process Communication (IPC) envelope for the corpus-ipc framework. Renamed from RuntimeMessage and SpineMessage per downstream migrations, it facilitates bidirectional communication between Rust-based simulation components (a stimulus producer and an SNN consumer) and external compute engines. The protocol handles spiking data, dense embeddings, continuous stimuli, neuromodulators, training feedback like gradients and eligibility traces, and control signals.
Sources: src/models/message.rs:13-57
The core envelope is the IpcMessage tagged enum, defined in src/models/message.rs. It derives Serialize, Deserialize, Debug, Clone, and PartialEq. Variant names (Spikes, Embeddings, Stimuli, Neuromodulators, Loss, ConfigUpdate, GradientUpdate, EligibilityTraces, TrainingComplete, Shutdown, Ping) act as serde identifiers and must remain stable across versions.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub enum IpcMessage {
// Input messages
Spikes(SpikeBatch),
Embeddings(EmbeddingBatch),
Stimuli(StimulusBatch),
Neuromodulators(NeuromodulatorSnapshot),
Loss(#[serde(deserialize_with = "de_loss")] f32),
ConfigUpdate(ConfigPayload),
// Output messages
GradientUpdate(GradientBatch),
EligibilityTraces(TraceBatch),
TrainingComplete,
// Control
Shutdown,
Ping,
}Variant-name stability is enforced via integration tests in src/models/compat.rs, ensuring JSON serialization retains the exact variant keys and round-trips correctly.
#[test]
fn ipc_message_envelopes_keep_variant_names() {
let spikes = serde_json::to_value(IpcMessage::Spikes(sample_spike_batch())).unwrap();
let traces = serde_json::to_value(IpcMessage::EligibilityTraces(sample_trace_batch())).unwrap();
assert!(spikes.get("Spikes").is_some());
assert!(traces.get("EligibilityTraces").is_some());
let decoded_spikes: IpcMessage = serde_json::from_value(spikes).unwrap();
let decoded_traces: IpcMessage = serde_json::from_value(traces).unwrap();
assert_eq!(decoded_spikes, IpcMessage::Spikes(sample_spike_batch()));
assert_eq!(
decoded_traces,
IpcMessage::EligibilityTraces(sample_trace_batch())
);
}Sources: src/models/message.rs:32-57, src/models/compat.rs:181-193
Messages within the envelope are grouped into three primary categories based on direction and role:
| Category | Variants | Primary Purpose |
|---|---|---|
| Input Messages |
Spikes, Embeddings, Stimuli, Neuromodulators, Loss, ConfigUpdate
|
Transmits sensor events, continuous streams, loss metrics, and configuration changes from Rust to external engines. |
| Output Messages |
GradientUpdate, EligibilityTraces, TrainingComplete
|
Returns gradients, eligibility traces, and training completion status from external engines to Rust. |
| Control Messages |
Shutdown, Ping
|
Manages connection lifecycle and latency monitoring. |
Sources: src/models/message.rs:34-57
To maintain correlation and traceability across the asynchronous IPC boundary, batch-oriented payloads wrapped by IpcMessage variants utilize session_id and batch_id fields.
graph TD
subgraph "CodeEntitySpace"
IM["IpcMessage [src/models/message.rs:33]"]
SB["SpikeBatch [src/models/message.rs:8]"]
GB["GradientBatch [src/models/message.rs:49]"]
TB["TraceBatch [src/models/message.rs:51]"]
end
subgraph "NaturalLanguageSpace"
SID["Session Correlation (session_id)"]
BID["Batch Correlation (batch_id)"]
end
IM -->|"Spikes"| SB
IM -->|"GradientUpdate"| GB
IM -->|"EligibilityTraces"| TB
SB -->|"Contains"| SID
SB -->|"Contains"| BID
GB -->|"Contains"| BID
Sources: src/models/message.rs:33-57, src/models/compat.rs:7-18
IpcMessage implements the Validate trait via validate_with(limits: ProtocolLimits), routing validation checks down to the inner batch types or primitive fields (such as finite-value checks on Loss).
impl Validate for IpcMessage {
fn validate_with(&self, limits: ProtocolLimits) -> Result<(), ValidationError> {
match self {
Self::Spikes(batch) => batch.validate_with(limits),
Self::Embeddings(batch) => batch.validate_with(limits),
Self::Stimuli(batch) => batch.validate_with(limits),
Self::Neuromodulators(snapshot) => snapshot.validate_with(limits),
Self::ConfigUpdate(payload) => payload.validate_with(limits),
Self::GradientUpdate(batch) => batch.validate_with(limits),
Self::EligibilityTraces(batch) => batch.validate_with(limits),
Self::Loss(value) => check_finite("Loss", *value),
Self::TrainingComplete | Self::Shutdown | Self::Ping => Ok(()),
}
}
}Sources: src/models/message.rs:59-73
The following diagram bridges natural language descriptions of the messaging architecture to concrete code entities in src/models/message.rs.
Title: "IpcMessage Processing and Validation Flow"
sequenceDiagram
participant Relay as "producer / client"
participant parser as "decode_ipc_message_json [src/lib.rs]"
participant msg as "IpcMessage [src/models/message.rs:33]"
participant val as "Validate::validate_with [src/models/message.rs:60]"
Relay->>parser: "JSON Payload"
parser->>msg: "Deserialize into IpcMessage Variant"
msg->>val: "Invoke validate_with(limits)"
alt Valid Payload
val-->>msg: "Ok(())"
else Invalid Payload / Non-Finite Loss
val-->>msg: "Err(ValidationError)"
end
Sources: src/models/message.rs:33-73, src/models/message.rs:5-11
- 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