Skip to content

Commit 221c666

Browse files
authored
Bandaid for intermittent hanging when hyper::body::to_bytes is called (eclipse-ibeji#80)
* Bandaid for intermittent hanging when hyper::body::to_bytes is called * Bandaid for intermittent hanging when hyper::body::to_bytes is called * Bandaid for intermittent hanging when hyper::body::to_bytes is called * Bandaid for intermittent hanging when hyper::body::to_bytes is called
1 parent 30a868d commit 221c666

File tree

3 files changed

+31
-11
lines changed

3 files changed

+31
-11
lines changed

README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,16 @@ Once you have installed the prerequisites, go to your enlistment's root director
108108

109109
This should build all of the libraries and executables.
110110

111-
### Tokio Console Support
111+
### <a name="tokio-console-support">Tokio Console Support</a>
112112

113113
Ibeji has support for using the [tokio console](https://github.com/tokio-rs/console) for advanced debugging. To enable this support, you need to build with the `tokio_console` feature enabled and with the `tokio_unstable` config flag for the rust compiler:
114114

115115
```bash
116116
RUSTFLAGS="--cfg tokio_unstable" cargo build --features tokio_console
117117
```
118118

119+
Read the [tokio console documentation](https://github.com/tokio-rs/console) to learn how to install tokio console and how to run it.
120+
119121
Note that the tokio console will intercept trace-level logs, so these will not be visible when debugging with the tokio console.
120122

121123
## <a name="running-the-tests">Running the Tests</a>

core/common/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ edition = "2021"
99
license = "MIT"
1010

1111
[dependencies]
12+
async-std = { workspace = true }
1213
bytes = { workspace = true }
1314
config = { workspace = true }
1415
core-protobuf-data-access = { path = "../protobuf_data_access" }

core/common/src/grpc_interceptor.rs

+27-10
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use dyn_clone::DynClone;
88
use futures_core::task::{Context, Poll};
99
use http::uri::Uri;
1010
use http_body::Body;
11+
use hyper::Method;
1112
use log::warn;
1213
use regex::Regex;
1314
use std::error::Error;
@@ -154,19 +155,35 @@ where
154155
let interceptor = self.interceptor.clone();
155156

156157
let (service_name, method_name) = Self::retrieve_grpc_names_from_uri(request.uri());
157-
let is_applicable = interceptor.is_applicable(&service_name, &method_name);
158+
let is_applicable = interceptor.is_applicable(&service_name, &method_name)
159+
&& (request.method() == Method::POST);
158160

159161
if is_applicable && interceptor.must_handle_request() {
160162
let (parts, body) = request.into_parts();
161-
let mut body_bytes: Bytes =
162-
match futures::executor::block_on(hyper::body::to_bytes(body)) {
163-
Ok(bytes) => bytes,
164-
Err(err) => {
165-
return Box::pin(async move {
166-
Err(Box::new(err) as Box<dyn std::error::Error + Sync + Send>)
167-
})
168-
}
169-
};
163+
164+
// There is a known issue where hyper::body::to_bytes sometimes hangs in the code below.
165+
// We will use a timeout to break out when this happens. This fix is a bandaid. We will
166+
// implement a better fix after we have upgraded to the latest major version of the hyper crate.
167+
let mut body_bytes: Bytes = match futures::executor::block_on(async {
168+
async_std::future::timeout(
169+
core::time::Duration::from_secs(5),
170+
hyper::body::to_bytes(body),
171+
)
172+
.await
173+
}) {
174+
Ok(Ok(bytes)) => bytes,
175+
Ok(Err(err)) => {
176+
return Box::pin(async move {
177+
Err(Box::new(err) as Box<dyn std::error::Error + Sync + Send>)
178+
});
179+
}
180+
Err(err) => {
181+
return Box::pin(async move {
182+
Err(Box::new(err) as Box<dyn std::error::Error + Sync + Send>)
183+
});
184+
}
185+
};
186+
170187
let protobuf_message_bytes: Bytes = body_bytes.split_off(GRPC_HEADER_LENGTH);
171188
let grpc_header_bytes = body_bytes;
172189
let new_protobuf_message_bytes: Bytes = match interceptor.handle_request(

0 commit comments

Comments
 (0)