Skip to content

Commit 8554904

Browse files
alexcrichtonseanmonstar
authored andcommitted
refactor(lib): convert usage of tokio_core::io to tokio_io
This commit updates to the most recent versions (released today) of the various Tokio libraries in use. Namely the `tokio_core::io` module has now been deprecated in favor of an external `tokio-io` crate. This commit pulls in that crate and uses the `AsyncRead + AsyncWrite` abstraction instead of `Io` from tokio-core. BREAKING CHANGE: Any external types that were using that had implemented `Io` will need to implement `AsyncRead + AsyncWrite` from tokio_io.
1 parent 34509ef commit 8554904

File tree

11 files changed

+118
-96
lines changed

11 files changed

+118
-96
lines changed

Cargo.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,17 @@ include = [
2222
[dependencies]
2323
base64 = "0.4"
2424
bytes = "0.4"
25-
futures = "0.1.7"
25+
futures = "0.1.11"
2626
futures-cpupool = "0.1"
2727
httparse = "1.0"
2828
language-tags = "0.2"
2929
log = "0.3"
3030
mime = "0.2"
31-
relay = "0.1"
3231
time = "0.1"
33-
tokio-core = "0.1"
32+
tokio-core = "0.1.6"
3433
tokio-proto = "0.1"
3534
tokio-service = "0.1"
35+
tokio-io = "0.1"
3636
unicase = "1.0"
3737
url = "1.0"
3838

src/client/connect.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::io;
33
//use std::net::SocketAddr;
44

55
use futures::{Future, Poll, Async};
6-
use tokio::io::Io;
6+
use tokio_io::{AsyncRead, AsyncWrite};
77
use tokio::reactor::Handle;
88
use tokio::net::{TcpStream, TcpStreamNew};
99
use tokio_service::Service;
@@ -18,7 +18,7 @@ use super::dns;
1818
/// `Request=Url` and `Response: Io` instead.
1919
pub trait Connect: Service<Request=Url, Error=io::Error> + 'static {
2020
/// The connected Io Stream.
21-
type Output: Io + 'static;
21+
type Output: AsyncRead + AsyncWrite + 'static;
2222
/// A Future that will resolve to the connected Stream.
2323
type Future: Future<Item=Self::Output, Error=io::Error> + 'static;
2424
/// Connect to a remote address.
@@ -27,7 +27,7 @@ pub trait Connect: Service<Request=Url, Error=io::Error> + 'static {
2727

2828
impl<T> Connect for T
2929
where T: Service<Request=Url, Error=io::Error> + 'static,
30-
T::Response: Io,
30+
T::Response: AsyncRead + AsyncWrite,
3131
T::Future: Future<Error=io::Error>,
3232
{
3333
type Output = T::Response;

src/client/mod.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ use std::rc::Rc;
1111
use std::time::Duration;
1212

1313
use futures::{Poll, Async, Future, Stream};
14-
use relay;
15-
use tokio::io::Io;
14+
use futures::unsync::oneshot;
15+
use tokio_io::{AsyncRead, AsyncWrite};
1616
use tokio::reactor::Handle;
1717
use tokio_proto::BindClient;
1818
use tokio_proto::streaming::Message;
@@ -149,12 +149,12 @@ where C: Connect,
149149
let pool_key = Rc::new(url[..::url::Position::BeforePath].to_owned());
150150
self.connector.connect(url)
151151
.map(move |io| {
152-
let (tx, rx) = relay::channel();
152+
let (tx, rx) = oneshot::channel();
153153
let client = HttpClient {
154154
client_rx: RefCell::new(Some(rx)),
155155
}.bind_client(&handle, io);
156156
let pooled = pool.pooled(pool_key, client);
157-
tx.complete(pooled.clone());
157+
drop(tx.send(pooled.clone()));
158158
pooled
159159
})
160160
};
@@ -207,11 +207,11 @@ impl<C, B> fmt::Debug for Client<C, B> {
207207
type TokioClient<B> = ClientProxy<Message<http::RequestHead, B>, Message<http::ResponseHead, TokioBody>, ::Error>;
208208

209209
struct HttpClient<B> {
210-
client_rx: RefCell<Option<relay::Receiver<Pooled<TokioClient<B>>>>>,
210+
client_rx: RefCell<Option<oneshot::Receiver<Pooled<TokioClient<B>>>>>,
211211
}
212212

213213
impl<T, B> ClientProto<T> for HttpClient<B>
214-
where T: Io + 'static,
214+
where T: AsyncRead + AsyncWrite + 'static,
215215
B: Stream<Error=::Error> + 'static,
216216
B::Item: AsRef<[u8]>,
217217
{
@@ -232,12 +232,12 @@ where T: Io + 'static,
232232
}
233233

234234
struct BindingClient<T, B> {
235-
rx: relay::Receiver<Pooled<TokioClient<B>>>,
235+
rx: oneshot::Receiver<Pooled<TokioClient<B>>>,
236236
io: Option<T>,
237237
}
238238

239239
impl<T, B> Future for BindingClient<T, B>
240-
where T: Io + 'static,
240+
where T: AsyncRead + AsyncWrite + 'static,
241241
B: Stream<Error=::Error>,
242242
B::Item: AsRef<[u8]>,
243243
{

src/client/pool.rs

+27-24
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::rc::Rc;
77
use std::time::{Duration, Instant};
88

99
use futures::{Future, Async, Poll};
10-
use relay;
10+
use futures::unsync::oneshot;
1111

1212
use http::{KeepAlive, KA};
1313

@@ -18,7 +18,7 @@ pub struct Pool<T> {
1818
struct PoolInner<T> {
1919
enabled: bool,
2020
idle: HashMap<Rc<String>, Vec<Entry<T>>>,
21-
parked: HashMap<Rc<String>, VecDeque<relay::Sender<Entry<T>>>>,
21+
parked: HashMap<Rc<String>, VecDeque<oneshot::Sender<Entry<T>>>>,
2222
timeout: Option<Duration>,
2323
}
2424

@@ -44,31 +44,33 @@ impl<T: Clone> Pool<T> {
4444

4545
fn put(&mut self, key: Rc<String>, entry: Entry<T>) {
4646
trace!("Pool::put {:?}", key);
47+
let mut inner = self.inner.borrow_mut();
48+
//let inner = &mut *inner;
4749
let mut remove_parked = false;
48-
let tx = self.inner.borrow_mut().parked.get_mut(&key).and_then(|parked| {
49-
let mut ret = None;
50+
let mut entry = Some(entry);
51+
if let Some(parked) = inner.parked.get_mut(&key) {
5052
while let Some(tx) = parked.pop_front() {
51-
if !tx.is_canceled() {
52-
ret = Some(tx);
53-
break;
53+
match tx.send(entry.take().unwrap()) {
54+
Ok(()) => break,
55+
Err(e) => {
56+
trace!("Pool::put removing canceled parked {:?}", key);
57+
entry = Some(e);
58+
}
5459
}
55-
trace!("Pool::put removing canceled parked {:?}", key);
5660
}
5761
remove_parked = parked.is_empty();
58-
ret
59-
});
62+
}
6063
if remove_parked {
61-
self.inner.borrow_mut().parked.remove(&key);
64+
inner.parked.remove(&key);
6265
}
6366

64-
if let Some(tx) = tx {
65-
trace!("Pool::put found parked {:?}", key);
66-
tx.complete(entry);
67-
} else {
68-
self.inner.borrow_mut()
69-
.idle.entry(key)
70-
.or_insert(Vec::new())
71-
.push(entry);
67+
match entry {
68+
Some(entry) => {
69+
inner.idle.entry(key)
70+
.or_insert(Vec::new())
71+
.push(entry);
72+
}
73+
None => trace!("Pool::put found parked {:?}", key),
7274
}
7375
}
7476

@@ -100,7 +102,7 @@ impl<T: Clone> Pool<T> {
100102
}
101103
}
102104

103-
fn park(&mut self, key: Rc<String>, tx: relay::Sender<Entry<T>>) {
105+
fn park(&mut self, key: Rc<String>, tx: oneshot::Sender<Entry<T>>) {
104106
trace!("Pool::park {:?}", key);
105107
self.inner.borrow_mut()
106108
.parked.entry(key)
@@ -191,7 +193,7 @@ struct Entry<T> {
191193
pub struct Checkout<T> {
192194
key: Rc<String>,
193195
pool: Pool<T>,
194-
parked: Option<relay::Receiver<Entry<T>>>,
196+
parked: Option<oneshot::Receiver<Entry<T>>>,
195197
}
196198

197199
impl<T: Clone> Future for Checkout<T> {
@@ -247,7 +249,7 @@ impl<T: Clone> Future for Checkout<T> {
247249
Some(entry) => Ok(Async::Ready(self.pool.reuse(self.key.clone(), entry))),
248250
None => {
249251
if self.parked.is_none() {
250-
let (tx, mut rx) = relay::channel();
252+
let (tx, mut rx) = oneshot::channel();
251253
let _ = rx.poll(); // park this task
252254
self.pool.park(self.key.clone(), tx);
253255
self.parked = Some(rx);
@@ -279,6 +281,7 @@ mod tests {
279281
use std::rc::Rc;
280282
use std::time::Duration;
281283
use futures::{Async, Future};
284+
use futures::future;
282285
use http::KeepAlive;
283286
use super::Pool;
284287

@@ -297,7 +300,7 @@ mod tests {
297300

298301
#[test]
299302
fn test_pool_checkout_returns_none_if_expired() {
300-
::futures::lazy(|| {
303+
future::lazy(|| {
301304
let pool = Pool::new(true, Some(Duration::from_secs(1)));
302305
let key = Rc::new("foo".to_string());
303306
let mut pooled = pool.pooled(key.clone(), 41);
@@ -339,7 +342,7 @@ mod tests {
339342
let pooled1 = pool.pooled(key.clone(), 41);
340343

341344
let mut pooled = pooled1.clone();
342-
let checkout = pool.checkout(&key).join(::futures::lazy(move || {
345+
let checkout = pool.checkout(&key).join(future::lazy(move || {
343346
// the checkout future will park first,
344347
// and then this lazy future will be polled, which will insert
345348
// the pooled back into the pool

src/http/conn.rs

+21-15
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::time::Instant;
55

66
use futures::{Poll, Async, AsyncSink, Stream, Sink, StartSend};
77
use futures::task::Task;
8-
use tokio::io::Io;
8+
use tokio_io::{AsyncRead, AsyncWrite};
99
use tokio_proto::streaming::pipeline::{Frame, Transport};
1010

1111
use header::{ContentLength, TransferEncoding};
@@ -16,7 +16,7 @@ use version::HttpVersion;
1616

1717

1818
/// This handles a connection, which will have been established over an
19-
/// `Io` (like a socket), and will likely include multiple
19+
/// `AsyncRead + AsyncWrite` (like a socket), and will likely include multiple
2020
/// `Transaction`s over HTTP.
2121
///
2222
/// The connection will determine when a message begins and ends as well as
@@ -29,7 +29,7 @@ pub struct Conn<I, B, T, K = KA> {
2929
}
3030

3131
impl<I, B, T, K> Conn<I, B, T, K>
32-
where I: Io,
32+
where I: AsyncRead + AsyncWrite,
3333
B: AsRef<[u8]>,
3434
T: Http1Transaction,
3535
K: KeepAlive
@@ -155,7 +155,7 @@ where I: Io,
155155
}
156156

157157
fn maybe_park_read(&mut self) {
158-
if self.io.poll_read().is_ready() {
158+
if !self.io.is_read_blocked() {
159159
// the Io object is ready to read, which means it will never alert
160160
// us that it is ready until we drain it. However, we're currently
161161
// finished reading, so we need to park the task to be able to
@@ -350,7 +350,7 @@ where I: Io,
350350
}
351351

352352
impl<I, B, T, K> Stream for Conn<I, B, T, K>
353-
where I: Io,
353+
where I: AsyncRead + AsyncWrite,
354354
B: AsRef<[u8]>,
355355
T: Http1Transaction,
356356
K: KeepAlive,
@@ -385,7 +385,7 @@ where I: Io,
385385
}
386386

387387
impl<I, B, T, K> Sink for Conn<I, B, T, K>
388-
where I: Io,
388+
where I: AsyncRead + AsyncWrite,
389389
B: AsRef<[u8]>,
390390
T: Http1Transaction,
391391
K: KeepAlive,
@@ -450,10 +450,15 @@ where I: Io,
450450
trace!("Conn::flush = {:?}", ret);
451451
ret
452452
}
453+
454+
fn close(&mut self) -> Poll<(), Self::SinkError> {
455+
try_ready!(self.poll_complete());
456+
self.io.io_mut().shutdown()
457+
}
453458
}
454459

455460
impl<I, B, T, K> Transport for Conn<I, B, T, K>
456-
where I: Io + 'static,
461+
where I: AsyncRead + AsyncWrite + 'static,
457462
B: AsRef<[u8]> + 'static,
458463
T: Http1Transaction + 'static,
459464
K: KeepAlive + 'static,
@@ -665,6 +670,7 @@ impl<'a, T: fmt::Debug + 'a, B: AsRef<[u8]> + 'a> fmt::Debug for DebugFrame<'a,
665670
#[cfg(test)]
666671
mod tests {
667672
use futures::{Async, Future, Stream, Sink};
673+
use futures::future;
668674
use tokio_proto::streaming::pipeline::Frame;
669675

670676
use http::{self, MessageHead, ServerTransaction};
@@ -705,7 +711,7 @@ mod tests {
705711

706712
#[test]
707713
fn test_conn_parse_partial() {
708-
let _: Result<(), ()> = ::futures::lazy(|| {
714+
let _: Result<(), ()> = future::lazy(|| {
709715
let good_message = b"GET / HTTP/1.1\r\nHost: foo.bar\r\n\r\n".to_vec();
710716
let io = AsyncIo::new_buf(good_message, 10);
711717
let mut conn = Conn::<_, http::Chunk, ServerTransaction>::new(io, Default::default());
@@ -772,7 +778,7 @@ mod tests {
772778

773779
#[test]
774780
fn test_conn_body_write_length() {
775-
let _: Result<(), ()> = ::futures::lazy(|| {
781+
let _: Result<(), ()> = future::lazy(|| {
776782
let io = AsyncIo::new_buf(vec![], 0);
777783
let mut conn = Conn::<_, http::Chunk, ServerTransaction>::new(io, Default::default());
778784
let max = ::http::io::MAX_BUFFER_SIZE + 4096;
@@ -800,7 +806,7 @@ mod tests {
800806

801807
#[test]
802808
fn test_conn_body_write_chunked() {
803-
let _: Result<(), ()> = ::futures::lazy(|| {
809+
let _: Result<(), ()> = future::lazy(|| {
804810
let io = AsyncIo::new_buf(vec![], 4096);
805811
let mut conn = Conn::<_, http::Chunk, ServerTransaction>::new(io, Default::default());
806812
conn.state.writing = Writing::Body(Encoder::chunked(), None);
@@ -813,7 +819,7 @@ mod tests {
813819

814820
#[test]
815821
fn test_conn_body_flush() {
816-
let _: Result<(), ()> = ::futures::lazy(|| {
822+
let _: Result<(), ()> = future::lazy(|| {
817823
let io = AsyncIo::new_buf(vec![], 1024 * 1024 * 5);
818824
let mut conn = Conn::<_, http::Chunk, ServerTransaction>::new(io, Default::default());
819825
conn.state.writing = Writing::Body(Encoder::length(1024 * 1024), None);
@@ -829,7 +835,7 @@ mod tests {
829835
#[test]
830836
fn test_conn_parking() {
831837
use std::sync::Arc;
832-
use futures::task::Unpark;
838+
use futures::executor::Unpark;
833839

834840
struct Car {
835841
permit: bool,
@@ -847,7 +853,7 @@ mod tests {
847853
}
848854

849855
// test that once writing is done, unparks
850-
let f = ::futures::lazy(|| {
856+
let f = future::lazy(|| {
851857
let io = AsyncIo::new_buf(vec![], 4096);
852858
let mut conn = Conn::<_, http::Chunk, ServerTransaction>::new(io, Default::default());
853859
conn.state.reading = Reading::KeepAlive;
@@ -861,7 +867,7 @@ mod tests {
861867

862868

863869
// test that flushing when not waiting on read doesn't unpark
864-
let f = ::futures::lazy(|| {
870+
let f = future::lazy(|| {
865871
let io = AsyncIo::new_buf(vec![], 4096);
866872
let mut conn = Conn::<_, http::Chunk, ServerTransaction>::new(io, Default::default());
867873
conn.state.writing = Writing::KeepAlive;
@@ -872,7 +878,7 @@ mod tests {
872878

873879

874880
// test that flushing and writing isn't done doesn't unpark
875-
let f = ::futures::lazy(|| {
881+
let f = future::lazy(|| {
876882
let io = AsyncIo::new_buf(vec![], 4096);
877883
let mut conn = Conn::<_, http::Chunk, ServerTransaction>::new(io, Default::default());
878884
conn.state.reading = Reading::KeepAlive;

src/http/h1/decode.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ mod tests {
295295
let (a, b) = self.split_at(n);
296296
let mut buf = BytesMut::from(a);
297297
*self = b;
298-
Ok(buf.drain_to(n).freeze())
298+
Ok(buf.split_to(n).freeze())
299299
} else {
300300
Ok(Bytes::new())
301301
}

0 commit comments

Comments
 (0)