Add user PING support (#346)

- Add `share::PingPong`, which can send `Ping`s, and poll for the `Pong`
  from the peer.
This commit is contained in:
Sean McArthur
2019-02-18 15:59:11 -08:00
committed by GitHub
parent 8a0b7ff64f
commit e3a73f726e
12 changed files with 458 additions and 31 deletions

View File

@@ -156,7 +156,7 @@
//! [`Builder`]: struct.Builder.html
//! [`Error`]: ../struct.Error.html
use {SendStream, RecvStream, ReleaseCapacity};
use {SendStream, RecvStream, ReleaseCapacity, PingPong};
use codec::{Codec, RecvError, SendError, UserError};
use frame::{Headers, Pseudo, Reason, Settings, StreamId};
use proto;
@@ -319,31 +319,13 @@ pub struct PushPromise {
response: PushedResponseFuture,
}
#[derive(Debug)]
/// A stream of pushed responses and corresponding promised requests
#[derive(Debug)]
#[must_use = "streams do nothing unless polled"]
pub struct PushPromises {
inner: proto::OpaqueStreamRef,
}
impl Stream for PushPromises {
type Item = PushPromise;
type Error = ::Error;
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
match try_ready!(self.inner.poll_pushed()) {
Some((request, response)) => {
let response = PushedResponseFuture {
inner: ResponseFuture {
inner: response, push_promise_consumed: false
}
};
Ok(Async::Ready(Some(PushPromise{request, response})))
}
None => Ok(Async::Ready(None)),
}
}
}
/// Builds client connections with custom configuration values.
///
/// Methods can be chained in order to set the configuration values.
@@ -1282,6 +1264,17 @@ where
assert!(size <= proto::MAX_WINDOW_SIZE);
self.inner.set_target_window_size(size);
}
/// Takes a `PingPong` instance from the connection.
///
/// # Note
///
/// This may only be called once. Calling multiple times will return `None`.
pub fn ping_pong(&mut self) -> Option<PingPong> {
self.inner
.take_user_pings()
.map(PingPong::new)
}
}
impl<T, B> Future for Connection<T, B>
@@ -1416,6 +1409,27 @@ impl ResponseFuture {
}
}
// ===== impl PushPromises =====
impl Stream for PushPromises {
type Item = PushPromise;
type Error = ::Error;
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
match try_ready!(self.inner.poll_pushed()) {
Some((request, response)) => {
let response = PushedResponseFuture {
inner: ResponseFuture {
inner: response, push_promise_consumed: false
}
};
Ok(Async::Ready(Some(PushPromise{request, response})))
}
None => Ok(Async::Ready(None)),
}
}
}
// ===== impl PushPromise =====
impl PushPromise {