tower/limit/concurrency/
future.rs

1//! [`Future`] types
2//!
3//! [`Future`]: std::future::Future
4use futures_core::ready;
5use pin_project_lite::pin_project;
6use std::{
7    future::Future,
8    pin::Pin,
9    task::{Context, Poll},
10};
11use tokio::sync::OwnedSemaphorePermit;
12
13pin_project! {
14    /// Future for the [`ConcurrencyLimit`] service.
15    ///
16    /// [`ConcurrencyLimit`]: crate::limit::ConcurrencyLimit
17    #[derive(Debug)]
18    pub struct ResponseFuture<T> {
19        #[pin]
20        inner: T,
21        // Keep this around so that it is dropped when the future completes
22        _permit: OwnedSemaphorePermit,
23    }
24}
25
26impl<T> ResponseFuture<T> {
27    pub(crate) fn new(inner: T, _permit: OwnedSemaphorePermit) -> ResponseFuture<T> {
28        ResponseFuture { inner, _permit }
29    }
30}
31
32impl<F, T, E> Future for ResponseFuture<F>
33where
34    F: Future<Output = Result<T, E>>,
35{
36    type Output = Result<T, E>;
37
38    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
39        Poll::Ready(ready!(self.project().inner.poll(cx)))
40    }
41}