use std::task::{Context, Poll}; #[cfg(feature = "http2")] use std::{future::Future, pin::Pin};
#[cfg(feature = "http2")] use http::{Request, Response}; #[cfg(feature = "http2")] use http_body::Body; #[cfg(feature = "http2")] use pin_project_lite::pin_project; use tokio::sync::{mpsc, oneshot};
pub(crate) type RetryPromise<T, U> = oneshot::Receiver<Result<U, TrySendError<T>>>; pub(crate) type Promise<T> = oneshot::Receiver<Result<T, crate::Error>>;
/// An error when calling `try_send_request`. /// /// There is a possibility of an error occurring on a connection in-between the /// time that a request is queued and when it is actually written to the IO /// transport. If that happens, it is safe to return the request back to the /// caller, as it was never fully sent. #[derive(Debug)] pubstruct TrySendError<T> { pub(crate) error: crate::Error, pub(crate) message: Option<T>,
}
/// A bounded sender of requests and callbacks for when responses are ready. /// /// While the inner sender is unbounded, the Giver is used to determine /// if the Receiver is ready for another request. pub(crate) struct Sender<T, U> { /// One message is always allowed, even if the Receiver hasn't asked /// for it yet. This boolean keeps track of whether we've sent one /// without notice. #[cfg(feature = "http1")]
buffered_once: bool, /// The Giver helps watch that the Receiver side has been polled /// when the queue is empty. This helps us know when a request and /// response have been fully processed, and a connection is ready /// for more.
giver: want::Giver, /// Actually bounded by the Giver, plus `buffered_once`.
inner: mpsc::UnboundedSender<Envelope<T, U>>,
}
/// An unbounded version. /// /// Cannot poll the Giver, but can still use it to determine if the Receiver /// has been dropped. However, this version can be cloned. #[cfg(feature = "http2")] pub(crate) struct UnboundedSender<T, U> { /// Only used for `is_closed`, since mpsc::UnboundedSender cannot be checked.
giver: want::SharedGiver,
inner: mpsc::UnboundedSender<Envelope<T, U>>,
}
#[cfg(feature = "http1")] fn can_send(&mutself) -> bool { ifself.giver.give() || !self.buffered_once { // If the receiver is ready *now*, then of course we can send. // // If the receiver isn't ready yet, but we don't have anything // in the channel yet, then allow one message. self.buffered_once = true; true
} else { false
}
}
impl<T, U> Drop for Receiver<T, U> { fn drop(&mutself) { // Notify the giver about the closure first, before dropping // the mpsc::Receiver. self.taker.cancel();
}
}
impl<T> TrySendError<T> { /// Take the message from this error. /// /// The message will not always have been recovered. If an error occurs /// after the message has been serialized onto the connection, it will not /// be available here. pubfn take_message(&mutself) -> Option<T> { self.message.take()
}
/// Returns a reference to the recovered message. /// /// The message will not always have been recovered. If an error occurs /// after the message has been serialized onto the connection, it will not /// be available here. pubfn message(&self) -> Option<&T> { self.message.as_ref()
}
/// Consumes this to return the inner error. pubfn into_error(self) -> crate::Error { self.error
}
/// Returns a reference to the inner error. pubfn error(&self) -> &crate::Error {
&self.error
}
}
#[cfg(not(miri))] #[tokio::test] asyncfn drop_receiver_sends_cancel_errors() { let _ = pretty_env_logger::try_init();
let (mut tx, mut rx) = channel::<Custom, ()>();
// must poll once for try_send to succeed
assert!(PollOnce(&mut rx).await.is_none(), "rx empty");
let promise = tx.try_send(Custom(43)).unwrap();
drop(rx);
let fulfilled = promise.await; let err = fulfilled
.expect("fulfilled")
.expect_err("promise should error"); match (err.error.is_canceled(), err.message) {
(true, Some(_)) => (),
e => panic!("expected Error::Cancel(_), found {:?}", e),
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.