At a high level, a protocol is a mechanism that lets you take a bunch of requests and turn them
into responses. Tower provides the
Service trait, which is
an interface for mapping requests into responses, but it does not deal with how those requests
are sent between clients and servers. Tokio, on the other hand, provides asynchronous
communication primitives, but it does not deal with high-level abstractions like services. This
crate attempts to bridge that gap.
There are many types of protocols in the wild, but they generally come in two forms:
pipelining and multiplexing. A pipelining protocol sends requests and responses in-order
between the consumer and provider of a service, and processes requests one at a time. A
multiplexing protocol on the other hand constructs requests in such a way that they can be
handled and responded to in any order while still allowing the client to know which response
is for which request. Pipelining and multiplexing both have their advantages and disadvantages;
see the module-level documentation for
multiplex for details. There is
also good deal of discussion in this StackOverflow
A key part of any protocol is its transport, which is the way that it transmits requests and
responses. In general,
tokio-tower leaves the on-the-wire implementations of protocols to
other crates (like
async-bincode) and instead operates at the level of
Streams. In particular, it
assumes that there exists a
Sink + Stream transport where it can send
Requests and receive
Responses, or vice-versa for the server side.
This crate provides utilities that make writing both clients and servers easier. You'll find
the client helper as
Client in the protocol module you're working with (e.g.,
pipeline::Client), and the server helper as
Server in the same place.
In a multiplexed protocol, the server responds to client requests in the order they complete.
Request IDs ([
In a pipelined protocol, the server responds to client requests in the order they were sent. Many requests can be in flight at the same time, but no request sees a response until all previous requests have been satisfied. Pipelined protocols can experience head-of-line blocking wherein a slow-to-process request prevents any subsequent request from being processed, but are often to easier to implement on the server side, and provide clearer request ordering semantics. Example pipelined protocols include HTTP/1.1, MySQL, and Redis.
An error that occurred while servicing a request.