feat(pubsub): implement streaming keep-alive logic#34653
Conversation
cf5df9b to
b1acc8a
Compare
94e9f14 to
ad59cd2
Compare
robertvoinescu-work
left a comment
There was a problem hiding this comment.
LGTM from a functional perspective. Just a few minor comments.
ca925d3 to
e53a9bd
Compare
This comment was marked as resolved.
This comment was marked as resolved.
26bcbb1 to
24055fd
Compare
This comment was marked as resolved.
This comment was marked as resolved.
2fa07a4 to
cca4878
Compare
aandreassa
left a comment
There was a problem hiding this comment.
Implementation looks great, just a couple of Ruby things & docs to think about!
43562dd to
f4927d5
Compare
5bdc0a7 to
d589b24
Compare
4e59244 to
d998c4f
Compare
Implement bi-directional keep-alive pings and pong liveness monitoring for Cloud Pub/Sub StreamingPull streams in Ruby. - Set protocol_version = 1 in initial StreamingPullRequest to negotiate keep-alive support. - Extract KeepaliveMonitor collaborator class to manage keep-alive ping/pong timestamps, liveness checks, and timeout restarts cleanly. - Disable liveness monitor evaluation during reconnect backoff and handshake phases to prevent false-positive restarts. - Add unit, integration, and live acceptance test suites.
346a70c to
3d9d3d1
Compare
| @@ -0,0 +1,85 @@ | |||
| # verify_keepalive.rb | |||
| @stopped = nil | ||
| @paused = nil | ||
| @pause_cond = new_cond | ||
| @backoff_cond = new_cond |
There was a problem hiding this comment.
A lightweight comment for each would be helpful since we have two versions now.
Could you please share what the bug was with only having one? Or point me to a test where you verify the behavior in case I missed it.
| assert wait_called | ||
| end | ||
|
|
||
| it "does not bleed self sentinel into the new request queue after restart_stream_for_timeout!" do |
There was a problem hiding this comment.
This test doesn't actually call restart_stream_for_timeout! or raise RestartStream. It manually pushes stream into the queue and directly calls private background_run.
Could we rewrite it to invoke it directly or simulate the monitor timing out? This way, we are testing the actual production path rather than manually stubbing internal variables.
…undant check for '.is_a?(Stream)'
…st boilerplate and encapsulation
…or user context per PR feedback
Overview
Implements proactive streaming keep-alive logic and connection health monitoring in
Google::Cloud::PubSub::MessageListener::Stream, mirroring the design implemented in the .NET Pub/Sub client (dotnet#15649).Long-running bi-directional gRPC streaming pull connections (
StreamingPull) can experience silent TCP drops, intermediary network timeouts, or read deadlocks during periods of low message volume. This change introduces background timer tasks to push regular keep-alive requests and actively monitor server Pong timestamps.Key Changes
protocol_version = 1on the initialStreamingPullRequestprotobuf to enable bi-directional stream keep-alive support.@stream_keepalive_task) to dispatch emptyStreamingPullRequestpings at regular intervals (default 30 seconds), regardless of current lease inventory volume.@pong_monitor_taskto inspect timestamps (@last_ping_at,@last_pong_at). If a keep-alive response is overdue by more thanpong_deadlineseconds (default 15 seconds), the monitor raisesRestartStreamto safely recycle the connection and back off.@last_ping_at = now if @last_pong_at >= @last_ping_at) to ensure consecutive un-ponged pings cannot overwrite the timestamp of an overdue request.Testing & Validation
keepalive_test.rb): Added targeted unit test coverage asserting protocol version flags, timer intervals, deadline timeouts, and non-disruptive Pong handling.helical-zone-771) across simulated TCP socket hangs, sub-millisecond deadline starvation, and post-recovery downstream message delivery.Fixes b/427319802