feat(client): add a Connection Pool

This adds a connection pool to the Client that is used by default. It
accepts any other NetworkConnector, and simply acts as a
NetworkConnector itself. Other Pools can exist by simply providing a
custom NetworkConnector. This Pool is only used by default if you also
use the default connector, which is `HttpConnector`. If you wish to use
the Pool with a custom connector, you'll need to create the Pool with
your custom connector, and then pass that pool to the
Client::with_connector.

This also adds a method to `NetworkStream`, `close`, which can be used
to know when the Stream should be put down, because a server requested
that the connection close instead of be kept alive.

Closes #363
Closes #41
This commit is contained in:
Sean McArthur
2015-01-23 13:15:15 -08:00
parent 362044c32c
commit 1e72a8ab3a
7 changed files with 281 additions and 15 deletions

View File

@@ -2,7 +2,7 @@
use std::any::{Any, TypeId};
use std::fmt;
use std::io::{self, Read, Write};
use std::net::{SocketAddr, ToSocketAddrs, TcpStream, TcpListener};
use std::net::{SocketAddr, ToSocketAddrs, TcpStream, TcpListener, Shutdown};
use std::mem;
use std::path::Path;
use std::sync::Arc;
@@ -57,6 +57,10 @@ impl<'a, N: NetworkListener + 'a> Iterator for NetworkConnections<'a, N> {
pub trait NetworkStream: Read + Write + Any + Send + Typeable {
/// Get the remote address of the underlying connection.
fn peer_addr(&mut self) -> io::Result<SocketAddr>;
/// This will be called when Stream should no longer be kept alive.
fn close(&mut self, _how: Shutdown) -> io::Result<()> {
Ok(())
}
}
/// A connector creates a NetworkStream.
@@ -123,6 +127,7 @@ impl NetworkStream + Send {
}
/// If the underlying type is T, extract it.
#[inline]
pub fn downcast<T: Any>(self: Box<NetworkStream + Send>)
-> Result<Box<T>, Box<NetworkStream + Send>> {
if self.is::<T>() {
@@ -277,12 +282,21 @@ impl Write for HttpStream {
}
impl NetworkStream for HttpStream {
#[inline]
fn peer_addr(&mut self) -> io::Result<SocketAddr> {
match *self {
HttpStream::Http(ref mut inner) => inner.0.peer_addr(),
HttpStream::Https(ref mut inner) => inner.get_mut().0.peer_addr()
}
}
#[inline]
fn close(&mut self, how: Shutdown) -> io::Result<()> {
match *self {
HttpStream::Http(ref mut inner) => inner.0.shutdown(how),
HttpStream::Https(ref mut inner) => inner.get_mut().0.shutdown(how)
}
}
}
/// A connector that will produce HttpStreams.