leizhiyuan opened a new pull request, #1479:
URL: https://github.com/apache/rocketmq-clients/pull/1479

   ### Which Issue(s) This PR Fixes
   
   Fixes #1478
   
   ### Brief Description
   
   Opening the telemetry stream had no upper bound. 
`establish_telemetry_stream` signs the request with `sign_without_timeout` on 
purpose, because a `grpc-timeout` would end the long-lived stream, but as a 
side effect the wait for the response headers of `self.stub.telemetry(request)` 
was not bounded either:
   
   - a peer that accepts the connection but never speaks was only cut off by 
the HTTP/2 keep-alive (`KEEP_ALIVE_INTERVAL` 60s + `KEEP_ALIVE_TIMEOUT` 30s);
   - a peer that still acks the pings (e.g. the proxy's telemetry handler is 
stuck before its first `onNext`) kept the caller waiting forever.
   
   This affects `Producer::start` and every first RPC to an endpoint, and 
`SessionManager::get_or_create_session` holds the session map lock meanwhile, 
so other RPCs queue behind it.
   
   This PR bounds only the wait for the response of the telemetry call by 
`ClientOption::timeout`, as suggested in the issue; once the server answered, 
the stream stays long-lived. `Session::start`, `Session::reconnect` and 
`Session::update_settings` all go through `establish_telemetry_stream` and are 
bounded by the same change. A timeout is reported as `ClientInternal` at 
`session.start` with the message `rpc telemetry timed out` and the `peer` / 
`timeout` in the context; other telemetry errors are reported as before.
   
   The session map lock granularity (#1448 / #1454) is out of scope; this 
change only bounds how long the lock can be held here.
   
   ### How Did You Test This Change?
   
   Added two tests in `rust/src/session.rs`, against a local tonic server that 
completes the HTTP/2 handshake and acks pings but never handles the RPC:
   
   - `session_start_fails_within_timeout_when_telemetry_is_never_answered`: the 
server never sends the response headers; `start` must fail within 
`ClientOption::timeout`. Before the fix it stayed pending until the 10s guard 
of the test.
   - `telemetry_stream_outlives_timeout_once_answered`: the server sends the 
headers and keeps the stream open; the stream must not be closed after 
`ClientOption::timeout`. Checked that it fails if the telemetry request carries 
a `grpc-timeout`.
   
   The reproduction of #1478 (`ClientOption::timeout` = 3s), before / after:
   
   ```
   silent_tcp: returned after 90.009680217s: Err("... send rpc telemetry 
failed, source: status: Unavailable, message: \"http2 error: keep-alive timed 
out\" ...")
   silent_h2: still pending after 120.001172491s
   ```
   
   ```
   silent_h2: returned after 3.002195299s: Err("Client internal error at 
client.start, context: { peer: 127.0.0.1:34185, timeout: 3s, called: 
session.start } => rpc telemetry timed out")
   silent_tcp: returned after 3.009530452s: Err("Client internal error at 
client.start, context: { peer: 127.0.0.1:39007, timeout: 3s, called: 
session.start } => rpc telemetry timed out")
   ```
   
   Locally:
   
   - `cargo test`: all passed (lib: 183 passed)
   - `cargo fmt --check`, `cargo clippy --all-features -- -D warnings`, `cargo 
doc --no-deps --all-features`: passed
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to