tokio_service/lib.rs
1//! Definition of the core `Service` trait to Tokio
2//!
3//! More information can be found on [the trait] itself.
4//!
5//! [the trait]: trait.Service.html
6
7#![deny(missing_docs)]
8
9extern crate futures;
10
11use futures::Future;
12
13use std::io;
14use std::rc::Rc;
15use std::sync::Arc;
16
17/// An asynchronous function from `Request` to a `Response`.
18///
19/// The `Service` trait is a simplified interface making it easy to write
20/// network applications in a modular and reusable way, decoupled from the
21/// underlying protocol. It is one of Tokio's fundamental abstractions.
22///
23/// # Functional
24///
25/// A `Service` is a function from a `Request`. It immediately returns a
26/// `Future` representing the eventual completion of processing the
27/// request. The actual request processing may happen at any time in the
28/// future, on any thread or executor. The processing may depend on calling
29/// other services. At some point in the future, the processing will complete,
30/// and the `Future` will resolve to a response or error.
31///
32/// At a high level, the `Service::call` represents an RPC request. The
33/// `Service` value can be a server or a client.
34///
35/// # Server
36///
37/// An RPC server *implements* the `Service` trait. Requests received by the
38/// server over the network are deserialized then passed as an argument to the
39/// server value. The returned response is sent back over the network.
40///
41/// As an example, here is how an HTTP request is processed by a server:
42///
43/// ```rust,ignore
44/// impl Service for HelloWorld {
45/// type Request = http::Request;
46/// type Response = http::Response;
47/// type Error = http::Error;
48/// type Future = Box<Future<Item = Self::Response, Error = http::Error>>;
49///
50/// fn call(&self, req: http::Request) -> Self::Future {
51/// // Create the HTTP response
52/// let resp = http::Response::ok()
53/// .with_body(b"hello world\n");
54///
55/// // Return the response as an immediate future
56/// futures::finished(resp).boxed()
57/// }
58/// }
59/// ```
60///
61/// # Client
62///
63/// A client consumes a service by using a `Service` value. The client may
64/// issue requests by invoking `call` and passing the request as an argument.
65/// It then receives the response by waiting for the returned future.
66///
67/// As an example, here is how a Redis request would be issued:
68///
69/// ```rust,ignore
70/// let client = redis::Client::new()
71/// .connect("127.0.0.1:6379".parse().unwrap())
72/// .unwrap();
73///
74/// let resp = client.call(Cmd::set("foo", "this is the value of foo"));
75///
76/// // Wait for the future to resolve
77/// println!("Redis response: {:?}", await(resp));
78/// ```
79///
80/// # Middleware
81///
82/// More often than not, all the pieces needed for writing robust, scalable
83/// network applications are the same no matter the underlying protocol. By
84/// unifying the API for both clients and servers in a protocol agnostic way,
85/// it is possible to write middleware that provide these pieces in a
86/// reusable way.
87///
88/// For example, take timeouts as an example:
89///
90/// ```rust,ignore
91/// use tokio::Service;
92/// use futures::Future;
93/// use std::time::Duration;
94///
95/// // Not yet implemented, but soon :)
96/// use tokio::timer::{Timer, Expired};
97///
98/// pub struct Timeout<T> {
99/// upstream: T,
100/// delay: Duration,
101/// timer: Timer,
102/// }
103///
104/// impl<T> Timeout<T> {
105/// pub fn new(upstream: T, delay: Duration) -> Timeout<T> {
106/// Timeout {
107/// upstream: upstream,
108/// delay: delay,
109/// timer: Timer::default(),
110/// }
111/// }
112/// }
113///
114/// impl<T> Service for Timeout<T>
115/// where T: Service,
116/// T::Error: From<Expired>,
117/// {
118/// type Request = T::Request;
119/// type Response = T::Response;
120/// type Error = T::Error;
121/// type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
122///
123/// fn call(&self, req: Self::Req) -> Self::Future {
124/// let timeout = self.timer.timeout(self.delay)
125/// .and_then(|timeout| Err(Self::Error::from(timeout)));
126///
127/// self.upstream.call(req)
128/// .select(timeout)
129/// .map(|(v, _)| v)
130/// .map_err(|(e, _)| e)
131/// .boxed()
132/// }
133/// }
134///
135/// ```
136///
137/// The above timeout implementation is decoupled from the underlying protocol
138/// and is also decoupled from client or server concerns. In other words, the
139/// same timeout middleware could be used in either a client or a server.
140pub trait Service {
141
142 /// Requests handled by the service.
143 type Request;
144
145 /// Responses given by the service.
146 type Response;
147
148 /// Errors produced by the service.
149 type Error;
150
151 /// The future response value.
152 type Future: Future<Item = Self::Response, Error = Self::Error>;
153
154 /// Process the request and return the response asynchronously.
155 fn call(&self, req: Self::Request) -> Self::Future;
156}
157
158/// Creates new `Service` values.
159pub trait NewService {
160 /// Requests handled by the service
161 type Request;
162
163 /// Responses given by the service
164 type Response;
165
166 /// Errors produced by the service
167 type Error;
168
169 /// The `Service` value created by this factory
170 type Instance: Service<Request = Self::Request, Response = Self::Response, Error = Self::Error>;
171
172 /// Create and return a new service value.
173 fn new_service(&self) -> io::Result<Self::Instance>;
174}
175
176impl<F, R> NewService for F
177 where F: Fn() -> io::Result<R>,
178 R: Service,
179{
180 type Request = R::Request;
181 type Response = R::Response;
182 type Error = R::Error;
183 type Instance = R;
184
185 fn new_service(&self) -> io::Result<R> {
186 (*self)()
187 }
188}
189
190impl<S: NewService + ?Sized> NewService for Arc<S> {
191 type Request = S::Request;
192 type Response = S::Response;
193 type Error = S::Error;
194 type Instance = S::Instance;
195
196 fn new_service(&self) -> io::Result<S::Instance> {
197 (**self).new_service()
198 }
199}
200
201impl<S: NewService + ?Sized> NewService for Rc<S> {
202 type Request = S::Request;
203 type Response = S::Response;
204 type Error = S::Error;
205 type Instance = S::Instance;
206
207 fn new_service(&self) -> io::Result<S::Instance> {
208 (**self).new_service()
209 }
210}
211
212impl<S: Service + ?Sized> Service for Box<S> {
213 type Request = S::Request;
214 type Response = S::Response;
215 type Error = S::Error;
216 type Future = S::Future;
217
218 fn call(&self, request: S::Request) -> S::Future {
219 (**self).call(request)
220 }
221}
222
223impl<S: Service + ?Sized> Service for Rc<S> {
224 type Request = S::Request;
225 type Response = S::Response;
226 type Error = S::Error;
227 type Future = S::Future;
228
229 fn call(&self, request: S::Request) -> S::Future {
230 (**self).call(request)
231 }
232}
233
234impl<S: Service + ?Sized> Service for Arc<S> {
235 type Request = S::Request;
236 type Response = S::Response;
237 type Error = S::Error;
238 type Future = S::Future;
239
240 fn call(&self, request: S::Request) -> S::Future {
241 (**self).call(request)
242 }
243}