This repository is a collection of Tokio (Rust async runtime) patterns and examples
Section 1. Manual Tokio Runtime Creation
Instead of using the #[tokio::main] macro, manually create a Tokio runtime
Section 2. Multithreaded Runtime
Configure the runtime to use 2 worker threads
This code demonstrates how to create a single-threaded Tokio runtime using new_current_thread() instead of a multi-threaded runtime.
Section 1: Async Function
This Rust code demonstrates basic asynchronous task spawning using the Tokio runtime.
This code demonstrates safe shared ownership of data across multiple asynchronous tasks using Arc
Section 3: Task Cancellation
This code demonstrates how to stop a running asynchronous task before it completes naturally.
This code demonstrates Rust's Send trait enforcement for data shared across asynchronous tasks.
This code demonstrates reference-counted thread-safe sharing of immutable data using Arc
Section 2. How a Mutex Shares Mutable State
This code demonstrates safe concurrent access to shared mutable state using Arc and Mutex
This code demonstrates how RwLock (Read-Write Lock) enables multiple concurrent readers while maintaining exclusive access for writers.
Section 4. How Semaphores Limit Concurrent Access
A semaphore is a synchronization primitive that limits the number of tasks that can access a resource simultaneously.
Section 5. Deadlock Prevention in Concurrent Code
A deadlock occurs when two or more tasks are waiting for each other to release resources, creating a circular dependency where none can proceed.
Section 6. How Barriers Work for Task Synchronization
A Barrier is a synchronization point where tasks must wait until a specified number of tasks reach that point, then all proceed together.
Section 7. How Notify Works for Signaling Between Tasks
Notify is a simple, lightweight synchronization primitive for signaling between tasks. One task waits for a signal, another task sends it.
Section 8. How Watch Channels Broadcast State Changes
This code demonstrates how a watch channel broadcasts state changes to multiple receivers, where each receiver can observe the latest value.
Section 1. Tokio MPSC Channel Explanation
This document demonstrates asynchronous communication between tasks using Tokio's multi-producer, single-consumer (mpsc) channel.
This code demonstrates Tokio's multi-producer, single-consumer (mpsc) channel pattern, where multiple concurrent tasks send messages to a single receiver.
Section 3. Tokio MPSC Backpressure Handling
This code demonstrates how Tokio's mpsc (multi-producer, single-consumer) channel handles backpressure using a bounded buffer.
Section 4. Oneshot Channel: Request-Response Pattern
A oneshot channel is a specialized communication primitive in Tokio designed for single-use, one-time message passing between asynchronous tasks.
Section 5. Understanding Tokio Broadcast Channels
This code demonstrates how to use Tokio's broadcast channel to send messages from one sender to multiple receivers concurrently.
When working with Tokio's mpsc channels, understanding how channel closure works is crucial for building reliable concurrent applications
Tokio's mpsc channels provide two main methods for sending messages: send() and try_send().
The request-response pattern is a common communication pattern where a client sends a request to a worker and waits for a response.
The tokio::select! macro allows you to wait on multiple async operations simultaneously and proceed with whichever completes first.
Section 1. Asynchronous File Reading in Rust with Tokio
This code explains how to write files asynchronously with Tokio.
Section 2. Asynchronous File Writing in Rust with Tokio
This code explains how to read files asynchronously with Tokio.
Section 3. Async File Copy in Rust with Tokio
This code explains how to read copy asynchronously with Tokio.
This code explains how to use Tokio's BufReader to read files asynchronously.
Section 5. TCP Echo Server in Rust with Tokio
This code implements a simple asynchronous TCP echo server using Rust and the Tokio runtime.
Section 6. TCP Client in Rust with Tokio
This code creates a TCP (Transmission Control Protocol) client that connects to a server, sends data, and receives a response.
Section 7. TCP Stream Splitting in Tokio
This document explains how Tokio allows you to split a TCP stream into separate read and write halves, enabling concurrent read and write operations on the same connection.
Section 8. TCP Stream Splitting in Tokio
This document explains how Tokio allows you to split a TCP stream into separate read and write halves, enabling concurrent read and write operations on the same connection.
This document explains how to add timeouts to asynchronous I/O operations in Rust using tokio::time::timeout.
Section 1. Understandi1ng LinesCodec in Tokio
LinesCodec is a decoder/encoder that handles newline-delimited text protocols.
Section 2. Framed TCP Messaging with SinkExt
This code demonstrates how to use SinkExt from the futures crate to send framed messages over a TCP stream in Rust.
The LengthDelimitedCodec from the tokio-util crate provides automatic message framing for TCP streams by prefixing each message with its length.
This document explains how to implement a custom decoder using Tokio's Decoder trait for a simple binary protocol.
This code implements a custom encoder for a simple binary protocol using Tokio's Encoder trait.
This code demonstrates how to create a unified codec struct that implements both the Encoder and Decoder traits from Tokio for bidirectional communication over network connections.
Section 7. JSON Codec with Length Prefixes
This code creates a custom codec that combines JSON serialization with length-delimited framing.
Section 8. Handling Partial Frames in a Custom Decoder
This decoder implements a length-prefixed protocol that gracefully handles partial frames - situations where a complete message hasn't arrived yet over the network.
Section 1. Future Trait Basics
When you declare a function with async fn, Rust automatically transforms it into a function that returns a type implementing Future.
Each async fn creates a unique, anonymous future type. Even though both functions have the same signature, they generate different types:
Section 3. Manual Future Implementation
The Future trait is the foundation of async/await in Rust:
This code demonstrates a fundamental async pattern: returning Pending to defer completion.
This code explains how pinning works in a self-referential struct.
An async block is a way to create a future inline.
tokio::join! is a macro that runs multiple futures concurrently and waits for all of them to complete:
tokio::try_join! is a variant of tokio::join! designed specifically for futures that return Result.
An executor is the runtime system that drives futures to completion.
The select! macro polls multiple async operations concurrently and proceeds with whichever one completes first.
This code demonstrates a common async pattern: attempting to receive a message from a channel with a timeout.
This code demonstrates how to use Rust's pattern matching to handle different types of messages received from a tokio channel.
This code demonstrates a common async pattern: attempting to receive a message from a channel with a timeout.
This code demonstrates how to use biased selection in tokio::select! to prioritize certain branches over others. By default, select!
This code demonstrates how to correctly handle cancellation-unsafe operations when using tokio::select!.
This code demonstrates how to use tokio::select! to concurrently wait on three different types of Tokio channels: MPSC, Oneshot, and Broadcast.
This code demonstrates a graceful shutdown pattern - one of the most important patterns in async Rust programming.
This code demonstrates a resetting timeout pattern - a technique where a timeout is continuously reset each time activity occurs.
Section 1. Iterating Over Streams with while let Some
This code demonstrates how to iterate over an async stream using the while let Some pattern.
Section 2. Creating Streams from Iterators with tokio
This code demonstrates how to convert a synchronous iterator (like a Vec) into an asynchronous Stream using tokio_stream::iter.
This code demonstrates how to use the map combinator to transform values in a stream.
This code demonstrates how to use the filter combinator to selectively keep values in a stream based on a condition.
This code demonstrates how to use the then combinator to perform asynchronous transformations on stream values.