1
0
mirror of https://github.com/fafhrd91/actix-net synced 2025-01-19 03:44:40 +01:00

eager drop in then, and_then, and_then_apply_fn (#72)

This commit is contained in:
Max Gortman 2019-12-05 20:34:44 -08:00 committed by Nikolay Kim
parent e670a32ff3
commit f89a992daf
3 changed files with 34 additions and 13 deletions

View File

@ -51,7 +51,7 @@ where
fn call(&mut self, req: A::Request) -> Self::Future { fn call(&mut self, req: A::Request) -> Self::Future {
AndThenServiceResponse { AndThenServiceResponse {
state: State::A(self.0.get_mut().0.call(req), self.0.clone()), state: State::A(self.0.get_mut().0.call(req), Some(self.0.clone())),
} }
} }
} }
@ -72,8 +72,9 @@ where
A: Service, A: Service,
B: Service<Request = A::Response, Error = A::Error>, B: Service<Request = A::Response, Error = A::Error>,
{ {
A(#[pin] A::Future, Cell<(A, B)>), A(#[pin] A::Future, Option<Cell<(A, B)>>),
B(#[pin] B::Future), B(#[pin] B::Future),
Empty,
} }
impl<A, B> Future for AndThenServiceResponse<A, B> impl<A, B> Future for AndThenServiceResponse<A, B>
@ -91,13 +92,19 @@ where
match this.state.as_mut().project() { match this.state.as_mut().project() {
State::A(fut, b) => match fut.poll(cx)? { State::A(fut, b) => match fut.poll(cx)? {
Poll::Ready(res) => { Poll::Ready(res) => {
let mut b = b.take().unwrap();
this.state.set(State::Empty); // drop fut A
let fut = b.get_mut().1.call(res); let fut = b.get_mut().1.call(res);
this.state.set(State::B(fut)); this.state.set(State::B(fut));
self.poll(cx) self.poll(cx)
} }
Poll::Pending => Poll::Pending, Poll::Pending => Poll::Pending,
}, },
State::B(fut) => fut.poll(cx), State::B(fut) => fut.poll(cx).map(|r| {
this.state.set(State::Empty);
r
}),
State::Empty => panic!("future must not be polled after it returned `Poll::Ready`"),
} }
} }
} }

View File

@ -79,7 +79,7 @@ where
fn call(&mut self, req: A::Request) -> Self::Future { fn call(&mut self, req: A::Request) -> Self::Future {
AndThenApplyFnFuture { AndThenApplyFnFuture {
state: State::A(self.a.call(req), self.b.clone()), state: State::A(self.a.call(req), Some(self.b.clone())),
} }
} }
} }
@ -108,8 +108,9 @@ where
Err: From<A::Error>, Err: From<A::Error>,
Err: From<B::Error>, Err: From<B::Error>,
{ {
A(#[pin] A::Future, Cell<(B, F)>), A(#[pin] A::Future, Option<Cell<(B, F)>>),
B(#[pin] Fut), B(#[pin] Fut),
Empty,
} }
impl<A, B, F, Fut, Res, Err> Future for AndThenApplyFnFuture<A, B, F, Fut, Res, Err> impl<A, B, F, Fut, Res, Err> Future for AndThenApplyFnFuture<A, B, F, Fut, Res, Err>
@ -130,6 +131,8 @@ where
match this.state.as_mut().project() { match this.state.as_mut().project() {
State::A(fut, b) => match fut.poll(cx)? { State::A(fut, b) => match fut.poll(cx)? {
Poll::Ready(res) => { Poll::Ready(res) => {
let mut b = b.take().unwrap();
this.state.set(State::Empty);
let b = b.get_mut(); let b = b.get_mut();
let fut = (&mut b.1)(res, &mut b.0); let fut = (&mut b.1)(res, &mut b.0);
this.state.set(State::B(fut)); this.state.set(State::B(fut));
@ -137,7 +140,11 @@ where
} }
Poll::Pending => Poll::Pending, Poll::Pending => Poll::Pending,
}, },
State::B(fut) => fut.poll(cx), State::B(fut) => fut.poll(cx).map(|r| {
this.state.set(State::Empty);
r
}),
State::Empty => panic!("future must not be polled after it returned `Poll::Ready`"),
} }
} }
} }

View File

@ -58,7 +58,7 @@ where
fn call(&mut self, req: A::Request) -> Self::Future { fn call(&mut self, req: A::Request) -> Self::Future {
ThenServiceResponse { ThenServiceResponse {
state: ThenServiceResponseState::A(self.a.call(req), self.b.clone()), state: State::A(self.a.call(req), Some(self.b.clone())),
} }
} }
} }
@ -70,17 +70,18 @@ where
B: Service<Request = Result<A::Response, A::Error>>, B: Service<Request = Result<A::Response, A::Error>>,
{ {
#[pin] #[pin]
state: ThenServiceResponseState<A, B>, state: State<A, B>,
} }
#[pin_project::pin_project] #[pin_project::pin_project]
enum ThenServiceResponseState<A, B> enum State<A, B>
where where
A: Service, A: Service,
B: Service<Request = Result<A::Response, A::Error>>, B: Service<Request = Result<A::Response, A::Error>>,
{ {
A(#[pin] A::Future, Cell<B>), A(#[pin] A::Future, Option<Cell<B>>),
B(#[pin] B::Future), B(#[pin] B::Future),
Empty
} }
impl<A, B> Future for ThenServiceResponse<A, B> impl<A, B> Future for ThenServiceResponse<A, B>
@ -96,15 +97,21 @@ where
#[project] #[project]
match this.state.as_mut().project() { match this.state.as_mut().project() {
ThenServiceResponseState::A(fut, b) => match fut.poll(cx) { State::A(fut, b) => match fut.poll(cx) {
Poll::Ready(res) => { Poll::Ready(res) => {
let mut b = b.take().unwrap();
this.state.set(State::Empty); // drop fut A
let fut = b.get_mut().call(res); let fut = b.get_mut().call(res);
this.state.set(ThenServiceResponseState::B(fut)); this.state.set(State::B(fut));
self.poll(cx) self.poll(cx)
} }
Poll::Pending => Poll::Pending, Poll::Pending => Poll::Pending,
}, },
ThenServiceResponseState::B(fut) => fut.poll(cx), State::B(fut) => fut.poll(cx).map(|r| {
this.state.set(State::Empty);
r
}),
State::Empty => panic!("future must not be polled after it returned `Poll::Ready`")
} }
} }
} }