Course contentsShow
← Rust
Lesson 1219 of 1,91010. Concurrency PrimitivesFree lesson

Asynchronous Stream Multiplexing

You will merge multiple network streams into a single logical data flow.

In this lesson, you will learn how to unify multiple independent asynchronous data sources into a single, cohesive stream using multiplexing.

The Problem: Managing Multiple Producers

In high-performance Rust applications, you often find yourself juggling several concurrent tasks—like listening to multiple network sockets or handling distinct message queues. While you could spawn a dedicated task for each, processing them individually creates "siloed" logic. Multiplexing allows you to collapse these multiple Stream inputs into one, enabling a single consumer loop to react to any available event regardless of its origin.

The Approach: Merging Streams

The goal is to transform a collection of streams (e.g., Stream<Item = T>) into a unified Stream<Item = T>. By doing this, your code becomes reactive to the first available piece of data across the entire set.

Think of it like a funnel: you have several pipes (streams) feeding into the top, and a single exit at the bottom where you handle whatever packet arrives next. In the tokio-stream ecosystem, this is commonly achieved using the merge utility.

use tokio_stream::{self as stream, StreamExt};

// Suppose we have two independent network sources
let stream_a = stream::iter(vec![1, 2, 3]);
let stream_b = stream::iter(vec![10, 20, 30]);

// Multiplex them into one logical flow
let mut multiplexed = stream::merge(stream_a, stream_b);

while let Some(val) = multiplexed.next().await {
    println!("Received: {}", val);
}

Why Multiplex?

When we multiplex, we avoid the overhead of task context switching and internal synchronization between separate worker threads. Instead of having multiple while let loops competing for CPU time or local state, we collapse the complexity into a single state machine. This is essential when you need to maintain a strict ordering or ensure that resources are processed as soon as they become ready, without "starving" one stream in favor of another.

By centralizing the ingestion, you gain a single point of instrumentation where you can apply flow control, rate limiting, or logging across all streams simultaneously.

Key Takeaway: Asynchronous stream multiplexing collapses multiple independent data sources into a single logical flow, simplifying your consumer logic and reducing task-switching overhead.