Course contentsShow
← Rust
Lesson 1657 of 1,91014. System Integration and EcosystemFree lesson

Inter-Process Communication

You will design robust message-passing systems between separate process boundaries.

In this lesson, you will learn how to design reliable message-passing architectures for communicating across independent process boundaries in Rust.

Beyond Shared Memory

When your application scales beyond a single address space, you can no longer rely on Arc<Mutex<T>> or shared pointers. Inter-Process Communication (IPC) forces us to treat every boundary as a potential point of failure. Because processes exist in isolated memory, you must serialize your data—usually via formats like bincode or serde_json—before sending it across a channel, such as a Unix Domain Socket, a named pipe, or a shared memory segment.

Designing Robust Boundaries

To build a resilient IPC system, treat your messages as a Protocol. Instead of passing raw bytes, define a strongly typed enum that represents all valid operations between the processes.

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, Debug)]
enum ServiceCommand {
    Compute(f64),
    Shutdown,
}

The key to robustness is managing the connection lifecycle. Unlike threads, processes can die silently. You should treat the channel as a Stream of results where the Err case represents a broken pipe or a crashed peer. Using tokio::net::UnixStream combined with a framing codec (like tokio-util's LengthDelimitedCodec) allows you to wrap these streams into a request/response pattern that handles framing issues automatically.

Handling Failure States

When designing IPC, always implement a "heartbeat" or a timeout mechanism. Because one process may hang or be terminated by the OS (e.g., an OOM killer), your receiver should use tokio::time::timeout on every read operation. This prevents your entire system from deadlocking if the peer stops responding. By combining these concepts, you transform raw OS-level primitives into a high-level, idiomatic message-passing architecture that treats process boundaries with the same rigor you apply to your internal module boundaries.

Key Takeaway: Robust IPC is achieved by treating your communication channel as a fallible, typed stream that mandates explicit serialization and strictly enforced timeout policies.