Return a concrete type from server::listen (#113)

* Return a concrete type from `server::listen`.
* Change `FutureServiceExt::listen` to return `(SocketAddr, Listen)`, where `Listen` is a struct created by the `service!` macro that `impls Future<Item=(),  Error=()>` and represents server execution.
* Disable `conservative_impl_trait` as it's no longer used.
* Update `FutureServiceExt` doc comment.
* Update `SyncServiceExt` doc comment. Also annotate `server::Handle` with `#[must_use]`.
* `cargo fmt`
This commit is contained in:
Tim
2017-02-21 22:01:59 -08:00
committed by GitHub
parent 44792347b1
commit 2b8f3db1fd
14 changed files with 326 additions and 116 deletions

View File

@@ -153,7 +153,7 @@ macro_rules! impl_deserialize {
/// Rpc methods are specified, mirroring trait syntax:
///
/// ```
/// # #![feature(conservative_impl_trait, plugin)]
/// # #![feature(plugin)]
/// # #![plugin(tarpc_plugins)]
/// # #[macro_use] extern crate tarpc;
/// # fn main() {}
@@ -446,25 +446,62 @@ macro_rules! service {
}
}
#[allow(non_camel_case_types)]
impl<tarpc_service_S__> $crate::tokio_service::NewService
for tarpc_service_AsyncServer__<tarpc_service_S__>
where tarpc_service_S__: FutureService
{
type Request = <Self as $crate::tokio_service::Service>::Request;
type Response = <Self as $crate::tokio_service::Service>::Response;
type Error = <Self as $crate::tokio_service::Service>::Error;
type Instance = Self;
fn new_service(&self) -> ::std::io::Result<Self> {
Ok(self.clone())
}
}
/// The future returned by `FutureServiceExt::listen`.
#[allow(unused)]
pub struct Listen<S>
where S: FutureService,
{
inner: $crate::server::Listen<tarpc_service_AsyncServer__<S>,
tarpc_service_Request__,
tarpc_service_Response__,
tarpc_service_Error__>,
}
impl<S> $crate::futures::Future for Listen<S>
where S: FutureService
{
type Item = ();
type Error = ();
fn poll(&mut self) -> $crate::futures::Poll<(), ()> {
self.inner.poll()
}
}
/// Provides a function for starting the service. This is a separate trait from
/// `FutureService` to prevent collisions with the names of RPCs.
pub trait FutureServiceExt: FutureService {
/// Spawns the service, binding to the given address and running on
/// the default tokio `Loop`.
/// the `reactor::Core` associated with `handle`.
///
/// Returns the address being listened on as well as the server future. The future
/// must be executed for the server to run.
fn listen(self,
addr: ::std::net::SocketAddr,
handle: &$crate::tokio_core::reactor::Handle,
options: $crate::server::Options)
-> ::std::io::Result<::std::net::SocketAddr>
-> ::std::io::Result<(::std::net::SocketAddr, Listen<Self>)>
{
$crate::server::listen(move || Ok(tarpc_service_AsyncServer__(self.clone())),
$crate::server::listen(tarpc_service_AsyncServer__(self),
addr,
handle,
options)
.map(|(addr_, server_)| {
handle.spawn(server_);
addr_
})
.map(|(addr, inner)| (addr, Listen { inner }))
}
}
@@ -485,8 +522,9 @@ macro_rules! service {
/// Provides a function for starting the service. This is a separate trait from
/// `SyncService` to prevent collisions with the names of RPCs.
pub trait SyncServiceExt: SyncService {
/// Spawns the service, binding to the given address and running on
/// the default tokio `Loop`.
/// Spawns the service, binding to the given address and returning the server handle.
///
/// To actually run the server, call `run` on the returned handle.
fn listen<A>(self, addr: A, options: $crate::server::Options)
-> ::std::io::Result<$crate::server::Handle>
where A: ::std::net::ToSocketAddrs
@@ -500,7 +538,7 @@ macro_rules! service {
let reactor_ = $crate::tokio_core::reactor::Core::new()?;
let (addr_, server_) = $crate::server::listen(
move || Ok(tarpc_service__.clone()),
tarpc_service__,
tarpc_service_addr__,
&reactor_.handle(),
options)?;
@@ -859,7 +897,8 @@ mod functional_test {
let options = get_tls_server_options();
let (tx, rx) = ::std::sync::mpsc::channel();
::std::thread::spawn(move || {
let mut handle = unwrap!(server.listen("localhost:0".first_socket_addr(), options));
let mut handle = unwrap!(server.listen("localhost:0".first_socket_addr(),
options));
tx.send(handle.addr()).unwrap();
handle.run();
});
@@ -874,9 +913,10 @@ mod functional_test {
{
let mut reactor = reactor::Core::new()?;
let server_options = get_tls_server_options();
let addr = server.listen("localhost:0".first_socket_addr(),
&reactor.handle(),
server_options)?;
let (addr, server) = server.listen("localhost:0".first_socket_addr(),
&reactor.handle(),
server_options)?;
reactor.handle().spawn(server);
let client_options = get_tls_client_options().handle(reactor.handle());
let client = unwrap!(reactor.run(C::connect(addr, client_options)));
Ok((addr, reactor, client))
@@ -888,9 +928,10 @@ mod functional_test {
{
let mut reactor = reactor::Core::new()?;
let server_options = get_tls_server_options();
let addr = server.listen("localhost:0".first_socket_addr(),
&reactor.handle(),
server_options)?;
let (addr, server) = server.listen("localhost:0".first_socket_addr(),
&reactor.handle(),
server_options)?;
reactor.handle().spawn(server);
let client_options = get_tls_client_options().handle(reactor.handle());
let client = unwrap!(reactor.run(C::connect(addr, client_options)));
Ok((addr, reactor, client))
@@ -916,7 +957,8 @@ mod functional_test {
let options = get_server_options();
let (tx, rx) = ::std::sync::mpsc::channel();
::std::thread::spawn(move || {
let mut handle = unwrap!(server.listen("localhost:0".first_socket_addr(), options));
let mut handle = unwrap!(server.listen("localhost:0".first_socket_addr(),
options));
tx.send(handle.addr()).unwrap();
handle.run();
});
@@ -931,9 +973,10 @@ mod functional_test {
{
let mut reactor = reactor::Core::new()?;
let options = get_server_options();
let addr = server.listen("localhost:0".first_socket_addr(),
let (addr, server) = server.listen("localhost:0".first_socket_addr(),
&reactor.handle(),
options)?;
reactor.handle().spawn(server);
let client = unwrap!(reactor.run(C::connect(addr, get_client_options())));
Ok((addr, reactor, client))
}
@@ -944,9 +987,10 @@ mod functional_test {
{
let mut reactor = reactor::Core::new()?;
let options = get_server_options();
let addr = server.listen("localhost:0".first_socket_addr(),
let (addr, server) = server.listen("localhost:0".first_socket_addr(),
&reactor.handle(),
options)?;
reactor.handle().spawn(server);
let client = C::connect(addr, get_client_options());
let client = unwrap!(reactor.run(client));
Ok((addr, reactor, client))
@@ -994,8 +1038,8 @@ mod functional_test {
}
mod future {
use futures::{Finished, finished};
use super::{FutureClient, FutureService, env_logger, start_server_with_async_client};
use futures::{Finished, finished};
use tokio_core::reactor;
use util::Never;
@@ -1059,7 +1103,7 @@ mod functional_test {
let _ = env_logger::init();
let reactor = reactor::Core::new().unwrap();
let addr = Server.listen("localhost:0".first_socket_addr(),
let (addr, _) = Server.listen("localhost:0".first_socket_addr(),
&reactor.handle(),
server::Options::default())
.unwrap();
@@ -1081,10 +1125,11 @@ mod functional_test {
assert_eq!("Hey, Tim.",
reactor.run(client.hey("Tim".to_string())).unwrap());
let addr = Server.listen("localhost:0".first_socket_addr(),
let (addr, server) = Server.listen("localhost:0".first_socket_addr(),
&reactor.handle(),
server::Options::default())
.unwrap();
reactor.handle().spawn(server);
let options = client::Options::default().handle(reactor.handle());
let client = reactor.run(FutureClient::connect(addr, options)).unwrap();
assert_eq!(3, reactor.run(client.add(1, 2)).unwrap());