Skip to content

Commit

Permalink
fix(examples): Fix tower examples (#624)
Browse files Browse the repository at this point in the history
Doing

```rust
let clone = self.inner.clone();
Box::pin(async move {
    let response = clone.call(request).await?;
    Ok(response)
})
```

If `self.inner` is (or contains) a `tower::buffer::Buffer` might panic.

That is because cloning a `Buffer` drops the permit that was acquired in
`poll_ready`, meaning it is no longer ready and panic in `call`.

The solution is to use `mem::replace` to take the ready service and pass
that into the async block.

Fixes #545
  • Loading branch information
davidpdrsn authored May 7, 2021
1 parent 4b26e78 commit 4a917a3
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 5 deletions.
9 changes: 7 additions & 2 deletions examples/src/tower/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,17 @@ mod service {
}

fn call(&mut self, req: Request<BoxBody>) -> Self::Future {
let mut channel = self.inner.clone();
// This is necessary because tonic internally uses `tower::buffer::Buffer`.
// See https://github.com/tower-rs/tower/issues/547#issuecomment-767629149
// for details on why this is necessary
let clone = self.inner.clone();
let mut inner = std::mem::replace(&mut self.inner, clone);

Box::pin(async move {
// Do extra async work here...
let response = inner.call(req).await?;

channel.call(req).await.map_err(Into::into)
Ok(response)
})
}
}
Expand Down
11 changes: 8 additions & 3 deletions examples/src/tower/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,17 @@ where
}

fn call(&mut self, req: HyperRequest<Body>) -> Self::Future {
let mut svc = self.inner.clone();
// This is necessary because tonic internally uses `tower::buffer::Buffer`.
// See https://github.com/tower-rs/tower/issues/547#issuecomment-767629149
// for details on why this is necessary
let clone = self.inner.clone();
let mut inner = std::mem::replace(&mut self.inner, clone);

Box::pin(async move {
// Do async work here....
// Do extra async work here...
let response = inner.call(req).await?;

svc.call(req).await
Ok(response)
})
}
}
Expand Down

0 comments on commit 4a917a3

Please sign in to comment.