google-cloud-pubsub 3.3.0 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2706c0520b9cd5aba014d233fddf25b3c5265cc35a30b65719ed91647a271bef
|
|
4
|
+
data.tar.gz: d6f9a3e8c9b74a08bd344582ce7c7e9b5a4bc03cebe0243ffb09ac17cdcc0afd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 426ac33d83d07732c22854216b673def03cf2b5813718a5e57428546f0e5499178d6848e75473da2e71169b79d76246879663d94f1ce8415758737efe6f5817a
|
|
7
|
+
data.tar.gz: b5def0275205fa9bd13ea1f463ce50992903ba2c423817f22401675ecfc1eb55e1ef57f9e97178d83659ee40fdc1e87a21075aa4180dfed177526e487d043327
|
data/CHANGELOG.md
CHANGED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Copyright 2026 Google LLC
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
require "concurrent"
|
|
16
|
+
|
|
17
|
+
module Google
|
|
18
|
+
module Cloud
|
|
19
|
+
module PubSub
|
|
20
|
+
class MessageListener
|
|
21
|
+
##
|
|
22
|
+
# @private
|
|
23
|
+
# Monitors gRPC streaming connection health via periodic bi-directional keep-alive pings and pongs.
|
|
24
|
+
#
|
|
25
|
+
# Tracks ping and pong timestamps over the active gRPC stream to detect silent connection drops or freezes,
|
|
26
|
+
# and triggers a stream restart when server responses exceed the configured pong deadline.
|
|
27
|
+
# This prevents firewalls and load balancers from dropping idle connections during periods of low
|
|
28
|
+
# message publisher volume, which minimizes message delivery latency by maintaining a healthy lease.
|
|
29
|
+
#
|
|
30
|
+
# For users, this ensures highly reliable, resilient, and responsive message delivery operations.
|
|
31
|
+
# It directly prevents issues where Google Cloud Pub/Sub subscribers may unexpectedly stall
|
|
32
|
+
# or stop receiving messages for extended periods due to unnotified intermediate network disruptions
|
|
33
|
+
# (e.g., TCP halfway drops). By proactively maintaining the connection's liveness, subscribers
|
|
34
|
+
# avoid sudden latency spikes and lost leases.
|
|
35
|
+
class KeepaliveMonitor
|
|
36
|
+
# Default interval in seconds between keep-alive ping requests.
|
|
37
|
+
DEFAULT_INTERVAL = 30.0
|
|
38
|
+
# Default deadline in seconds to receive a keep-alive pong response.
|
|
39
|
+
DEFAULT_DEADLINE = 15.0
|
|
40
|
+
# Divisor applied to keep-alive interval to calculate monitor polling interval (1/5th of interval).
|
|
41
|
+
MONITOR_DIVISOR = 5.0
|
|
42
|
+
# Minimum floor in seconds (10ms) for the monitor polling interval to prevent CPU spinning.
|
|
43
|
+
MIN_MONITOR_INTERVAL = 0.01
|
|
44
|
+
|
|
45
|
+
# Initializes the KeepaliveMonitor.
|
|
46
|
+
#
|
|
47
|
+
# @param [Stream] stream The parent streaming pull connection to monitor.
|
|
48
|
+
# @param [Float] interval The interval in seconds between keep-alive pings.
|
|
49
|
+
# @param [Float] deadline The deadline in seconds for receiving a pong.
|
|
50
|
+
def initialize stream, interval: DEFAULT_INTERVAL, deadline: DEFAULT_DEADLINE
|
|
51
|
+
@stream = stream
|
|
52
|
+
@interval = interval
|
|
53
|
+
@deadline = deadline
|
|
54
|
+
@last_ping_at = nil
|
|
55
|
+
@last_pong_at = nil
|
|
56
|
+
@ping_task = nil
|
|
57
|
+
@monitor_task = nil
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Starts the background keep-alive ping and liveness monitor timer tasks.
|
|
61
|
+
#
|
|
62
|
+
# @return [KeepaliveMonitor] self for chaining.
|
|
63
|
+
def start
|
|
64
|
+
@stream.synchronize do
|
|
65
|
+
return self if @ping_task
|
|
66
|
+
|
|
67
|
+
@ping_task = Concurrent::TimerTask.new(execution_interval: [@interval, MIN_MONITOR_INTERVAL].max) do
|
|
68
|
+
send_ping!
|
|
69
|
+
end
|
|
70
|
+
@ping_task.execute
|
|
71
|
+
|
|
72
|
+
@monitor_task = Concurrent::TimerTask.new(
|
|
73
|
+
execution_interval: [@interval / MONITOR_DIVISOR, MIN_MONITOR_INTERVAL].max
|
|
74
|
+
) do
|
|
75
|
+
check_liveness!
|
|
76
|
+
end
|
|
77
|
+
@monitor_task.execute
|
|
78
|
+
end
|
|
79
|
+
self
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Shuts down and cleans up the background keep-alive and monitor timer tasks.
|
|
83
|
+
#
|
|
84
|
+
# @return [KeepaliveMonitor] self for chaining.
|
|
85
|
+
def stop
|
|
86
|
+
@stream.synchronize do
|
|
87
|
+
@ping_task&.shutdown
|
|
88
|
+
@ping_task = nil
|
|
89
|
+
@monitor_task&.shutdown
|
|
90
|
+
@monitor_task = nil
|
|
91
|
+
end
|
|
92
|
+
self
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Records the initial stream handshake by setting ping and pong timestamps to the current monotonic time.
|
|
96
|
+
#
|
|
97
|
+
# @return [void]
|
|
98
|
+
def record_handshake!
|
|
99
|
+
@stream.synchronize do
|
|
100
|
+
now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
101
|
+
@last_ping_at = now
|
|
102
|
+
@last_pong_at = now
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Records a received pong by updating the last pong timestamp to the current monotonic time.
|
|
107
|
+
#
|
|
108
|
+
# @return [void]
|
|
109
|
+
def record_pong!
|
|
110
|
+
@stream.synchronize do
|
|
111
|
+
@stream.log_info "received keepAlive pong from stream for subscription #{@stream.subscriber.subscription_name}"
|
|
112
|
+
@last_pong_at = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Evaluates stream state and sends a bi-directional keep-alive ping if appropriate.
|
|
117
|
+
#
|
|
118
|
+
# @return [void]
|
|
119
|
+
def send_ping!
|
|
120
|
+
@stream.synchronize do
|
|
121
|
+
# Push unconditional keep-alive pings only when the stream is actively open and request queue is active.
|
|
122
|
+
# Note: ACKs are sent via unary RPCs (TimedUnaryBuffer), not over this stream.
|
|
123
|
+
return unless @stream.stream_open? && !@stream.stopped? && @stream.request_queue_active?
|
|
124
|
+
|
|
125
|
+
@stream.log_info "sending keepAlive to stream for subscription #{@stream.subscriber.subscription_name}"
|
|
126
|
+
# Only advance @last_ping_at if the previous ping was successfully ponged.
|
|
127
|
+
# If a pong is outstanding (@last_pong_at < @last_ping_at), freezing @last_ping_at preserves the start time
|
|
128
|
+
# of the un-ponged cycle so check_liveness! can accurately evaluate the elapsed deadline.
|
|
129
|
+
@last_ping_at = Process.clock_gettime(Process::CLOCK_MONOTONIC) if @last_pong_at.nil? || @last_ping_at.nil? || @last_pong_at >= @last_ping_at
|
|
130
|
+
@stream.send_ping_request!
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Checks whether a pong response has been received within the configured deadline,
|
|
135
|
+
# and triggers a stream restart if the deadline has been exceeded.
|
|
136
|
+
#
|
|
137
|
+
# @return [void]
|
|
138
|
+
def check_liveness!
|
|
139
|
+
@stream.synchronize do
|
|
140
|
+
# Do not check pong deadline if paused (client flow control inventory full).
|
|
141
|
+
# When paused, background_run waits on condition variable and stops calling enum.next,
|
|
142
|
+
# so incoming server pongs sit buffered in gRPC and last_pong_at stays un-updated.
|
|
143
|
+
return unless @stream.stream_open? && @last_ping_at && @last_pong_at && !@stream.stopped? && !@stream.paused?
|
|
144
|
+
|
|
145
|
+
now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
146
|
+
if now - @last_ping_at >= @deadline && @last_pong_at < @last_ping_at
|
|
147
|
+
elapsed_pong = (now - @last_pong_at).round(2)
|
|
148
|
+
@stream.log_error "Keep-alive pong not received within #{@deadline}s (last pong #{elapsed_pong}s ago); restarting stream."
|
|
149
|
+
@stream.restart_stream_for_timeout!
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
Pubsub = PubSub unless const_defined? :Pubsub
|
|
158
|
+
end
|
|
159
|
+
end
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
require "google/cloud/pubsub/message_listener/sequencer"
|
|
16
16
|
require "google/cloud/pubsub/message_listener/enumerator_queue"
|
|
17
17
|
require "google/cloud/pubsub/message_listener/inventory"
|
|
18
|
+
require "google/cloud/pubsub/message_listener/keepalive_monitor"
|
|
18
19
|
require "google/cloud/pubsub/service"
|
|
19
20
|
require "google/cloud/errors"
|
|
20
21
|
require "monitor"
|
|
@@ -49,6 +50,25 @@ module Google
|
|
|
49
50
|
# @private exactly_once_delivery_enabled.
|
|
50
51
|
attr_reader :exactly_once_delivery_enabled
|
|
51
52
|
|
|
53
|
+
##
|
|
54
|
+
# @private KeepaliveMonitor.
|
|
55
|
+
attr_reader :keepalive_monitor
|
|
56
|
+
|
|
57
|
+
# Initial backoff delay in seconds when reconnecting after a transient stream disconnection.
|
|
58
|
+
INITIAL_RECONNECT_DELAY = 1.0
|
|
59
|
+
|
|
60
|
+
# Maximum backoff delay in seconds for stream reconnection attempts.
|
|
61
|
+
MAX_RECONNECT_DELAY = 60.0
|
|
62
|
+
|
|
63
|
+
# Exponential backoff multiplier applied to reconnect delay on successive retry attempts.
|
|
64
|
+
RECONNECT_BACKOFF_MULTIPLIER = 1.5
|
|
65
|
+
|
|
66
|
+
# Inventory capacity ratio (80%) below which a flow-control paused stream will unpause.
|
|
67
|
+
UNPAUSE_INVENTORY_RATIO = 0.8
|
|
68
|
+
|
|
69
|
+
# The keep-alive streaming pull protocol version sent in the initial request during handshake.
|
|
70
|
+
PROTOCOL_VERSION = 1
|
|
71
|
+
|
|
52
72
|
##
|
|
53
73
|
# @private Create an empty Subscriber::Stream object.
|
|
54
74
|
def initialize subscriber
|
|
@@ -59,7 +79,12 @@ module Google
|
|
|
59
79
|
@request_queue = nil
|
|
60
80
|
@stopped = nil
|
|
61
81
|
@paused = nil
|
|
82
|
+
# Condition variable used to cooperatively pause the background thread during flow control
|
|
83
|
+
# Governed by the Stream's MonitorMixin `synchronize` lock.
|
|
62
84
|
@pause_cond = new_cond
|
|
85
|
+
# Condition variable used to cooperatively sleep the background thread during connection retries
|
|
86
|
+
# Governed by the Stream's MonitorMixin `synchronize` lock.
|
|
87
|
+
@backoff_cond = new_cond
|
|
63
88
|
@exactly_once_delivery_enabled = false
|
|
64
89
|
|
|
65
90
|
@inventory = Inventory.new self, **@subscriber.stream_inventory
|
|
@@ -68,17 +93,9 @@ module Google
|
|
|
68
93
|
|
|
69
94
|
@callback_thread_pool = Concurrent::ThreadPoolExecutor.new max_threads: @subscriber.callback_threads
|
|
70
95
|
|
|
71
|
-
@
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
# push empty request every 30 seconds to keep stream alive
|
|
75
|
-
unless inventory.empty?
|
|
76
|
-
subscriber.service.logger.log :info, "subscriber-streams" do
|
|
77
|
-
"sending keepAlive to stream for subscription #{@subscriber.subscription_name}"
|
|
78
|
-
end
|
|
79
|
-
push Google::Cloud::PubSub::V1::StreamingPullRequest.new
|
|
80
|
-
end
|
|
81
|
-
end.execute
|
|
96
|
+
@keepalive_monitor = KeepaliveMonitor.new self
|
|
97
|
+
@stream_open = false
|
|
98
|
+
@reconnect_delay = nil
|
|
82
99
|
end
|
|
83
100
|
|
|
84
101
|
def start
|
|
@@ -86,6 +103,7 @@ module Google
|
|
|
86
103
|
break if @background_thread
|
|
87
104
|
|
|
88
105
|
@inventory.start
|
|
106
|
+
@keepalive_monitor.start
|
|
89
107
|
|
|
90
108
|
start_streaming!
|
|
91
109
|
end
|
|
@@ -107,6 +125,9 @@ module Google
|
|
|
107
125
|
# Signal to the background thread that we are stopped.
|
|
108
126
|
@stopped = true
|
|
109
127
|
@pause_cond.broadcast
|
|
128
|
+
@backoff_cond.broadcast
|
|
129
|
+
|
|
130
|
+
@keepalive_monitor.stop
|
|
110
131
|
|
|
111
132
|
# Now that the reception thread is stopped, immediately stop the
|
|
112
133
|
# callback thread pool. All queued callbacks will see the stream
|
|
@@ -124,6 +145,10 @@ module Google
|
|
|
124
145
|
synchronize { @stopped }
|
|
125
146
|
end
|
|
126
147
|
|
|
148
|
+
def stream_open?
|
|
149
|
+
synchronize { @stream_open }
|
|
150
|
+
end
|
|
151
|
+
|
|
127
152
|
def paused?
|
|
128
153
|
synchronize { @paused }
|
|
129
154
|
end
|
|
@@ -139,6 +164,38 @@ module Google
|
|
|
139
164
|
self
|
|
140
165
|
end
|
|
141
166
|
|
|
167
|
+
|
|
168
|
+
def request_queue_active?
|
|
169
|
+
!@request_queue.nil?
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def send_ping_request!
|
|
173
|
+
push Google::Cloud::PubSub::V1::StreamingPullRequest.new
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def restart_stream_for_timeout!
|
|
177
|
+
synchronize do
|
|
178
|
+
@stream_open = false
|
|
179
|
+
# Push self as a stream-closing sentinel to @request_queue.
|
|
180
|
+
# When EnumeratorQueue#each pops the sentinel object, it terminates the request enumerator,
|
|
181
|
+
# cleanly sending an HTTP/2 END_STREAM flag and unblocking the write-side gRPC C-core pipeline.
|
|
182
|
+
@request_queue&.push self
|
|
183
|
+
@background_thread&.raise RestartStream
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def log_info msg
|
|
188
|
+
subscriber.service.logger.log :info, "subscriber-streams" do
|
|
189
|
+
msg
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def log_error msg
|
|
194
|
+
subscriber.service.logger.log :error, "subscriber-streams" do
|
|
195
|
+
msg
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
142
199
|
##
|
|
143
200
|
# @private
|
|
144
201
|
def acknowledge *messages, &callback
|
|
@@ -219,6 +276,15 @@ module Google
|
|
|
219
276
|
|
|
220
277
|
# rubocop:disable all
|
|
221
278
|
|
|
279
|
+
def backoff_and_wait!
|
|
280
|
+
@reconnect_delay = @reconnect_delay ? [@reconnect_delay * RECONNECT_BACKOFF_MULTIPLIER, MAX_RECONNECT_DELAY].min : INITIAL_RECONNECT_DELAY
|
|
281
|
+
synchronize do
|
|
282
|
+
# Disable liveness checker during backoff sleep to prevent monitor task from interrupting and double-backing off
|
|
283
|
+
@stream_open = false
|
|
284
|
+
@backoff_cond.wait(@reconnect_delay + rand(0.0..0.5)) unless @stopped
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
|
|
222
288
|
def background_run
|
|
223
289
|
synchronize do
|
|
224
290
|
# Don't allow a stream to restart if already stopped
|
|
@@ -240,16 +306,32 @@ module Google
|
|
|
240
306
|
# Always create a new request queue
|
|
241
307
|
@request_queue = EnumeratorQueue.new self
|
|
242
308
|
@request_queue.push initial_input_request
|
|
243
|
-
old_queue.each
|
|
309
|
+
old_queue.each do |obj|
|
|
310
|
+
@request_queue.push obj unless obj == self
|
|
311
|
+
end
|
|
244
312
|
end
|
|
245
313
|
|
|
246
314
|
# Call the StreamingPull API to get the response enumerator
|
|
247
315
|
options = { :"metadata" => { :"x-goog-request-params" => @subscriber.subscription_name } }
|
|
316
|
+
# Temporarily disable the liveness monitor while establishing the gRPC connection
|
|
317
|
+
# to prevent check_liveness! from evaluating stale timestamps during the handshake.
|
|
318
|
+
synchronize do
|
|
319
|
+
@stream_open = false
|
|
320
|
+
end
|
|
248
321
|
enum = @subscriber.service.streaming_pull @request_queue.each, options
|
|
249
322
|
subscriber.service.logger.log :info, "subscriber-streams" do
|
|
250
323
|
"rpc: streamingPull, subscription: #{@subscriber.subscription_name}, stream opened"
|
|
251
324
|
end
|
|
252
325
|
|
|
326
|
+
# Once the stream handshake completes, initialize ping/pong timestamps to monotonic now
|
|
327
|
+
# and mark @stream_open = true under synchronization.
|
|
328
|
+
# This ensures @keepalive_monitor evaluates liveness against a fresh window and prevents
|
|
329
|
+
# false-positive disconnect detections from stale timestamps prior to reconnecting.
|
|
330
|
+
synchronize do
|
|
331
|
+
@keepalive_monitor.record_handshake!
|
|
332
|
+
@stream_open = true
|
|
333
|
+
end
|
|
334
|
+
|
|
253
335
|
loop do
|
|
254
336
|
synchronize do
|
|
255
337
|
if @paused && !@stopped
|
|
@@ -264,8 +346,17 @@ module Google
|
|
|
264
346
|
begin
|
|
265
347
|
# Cannot synchronize the enumerator, causes deadlock
|
|
266
348
|
response = enum.next
|
|
267
|
-
|
|
349
|
+
synchronize do
|
|
350
|
+
@keepalive_monitor.record_pong!
|
|
351
|
+
# Reset backoff delay only after successfully reading a frame from enum.next.
|
|
352
|
+
# If the connection drops immediately upon reading, @reconnect_delay is preserved.
|
|
353
|
+
@reconnect_delay = nil
|
|
354
|
+
end
|
|
268
355
|
received_messages = response.received_messages
|
|
356
|
+
# Skip processing properties and inventory on Pong frames (empty received_messages).
|
|
357
|
+
# Subscription properties on keep-alive Pongs are not valid.
|
|
358
|
+
next if received_messages.empty?
|
|
359
|
+
new_exactly_once_delivery_enabled = response&.subscription_properties&.exactly_once_delivery_enabled
|
|
269
360
|
|
|
270
361
|
# Use synchronize so changes happen atomically
|
|
271
362
|
synchronize do
|
|
@@ -310,11 +401,13 @@ module Google
|
|
|
310
401
|
"#{status_code}; will be retried."
|
|
311
402
|
end
|
|
312
403
|
# Restart the stream with an incremental back for a retriable error.
|
|
404
|
+
backoff_and_wait!
|
|
313
405
|
retry
|
|
314
406
|
rescue RestartStream
|
|
315
407
|
subscriber.service.logger.log :info, "subscriber-streams" do
|
|
316
408
|
"Subscriber stream for subscription #{@subscriber.subscription_name} has ended; will be retried."
|
|
317
409
|
end
|
|
410
|
+
backoff_and_wait!
|
|
318
411
|
retry
|
|
319
412
|
rescue StandardError => e
|
|
320
413
|
subscriber.service.logger.log :error, "subscriber-streams" do
|
|
@@ -322,6 +415,7 @@ module Google
|
|
|
322
415
|
end
|
|
323
416
|
@subscriber.error! e
|
|
324
417
|
|
|
418
|
+
backoff_and_wait!
|
|
325
419
|
retry
|
|
326
420
|
end
|
|
327
421
|
|
|
@@ -417,21 +511,27 @@ module Google
|
|
|
417
511
|
end
|
|
418
512
|
|
|
419
513
|
def unpause_streaming!
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
514
|
+
synchronize do
|
|
515
|
+
return unless unpause_streaming?
|
|
516
|
+
|
|
517
|
+
@paused = nil
|
|
518
|
+
# Record pong when unpausing flow control. While paused, incoming server pongs sit buffered in gRPC,
|
|
519
|
+
# leaving last_pong_at stale. Updating timestamp guarantees the monitor thread will not trigger an immediate
|
|
520
|
+
# false-positive restart while the reader thread wakes up to drain buffered frames.
|
|
521
|
+
@keepalive_monitor.record_pong!
|
|
522
|
+
subscriber.service.logger.log :info, "subscriber-flow-control" do
|
|
523
|
+
"subscriber for #{@subscriber.subscription_name} is unblocking client-side flow control"
|
|
524
|
+
end
|
|
525
|
+
# Signal to the background thread that we are unpaused
|
|
526
|
+
@pause_cond.broadcast
|
|
425
527
|
end
|
|
426
|
-
# signal to the background thread that we are unpaused
|
|
427
|
-
@pause_cond.broadcast
|
|
428
528
|
end
|
|
429
529
|
|
|
430
530
|
def unpause_streaming?
|
|
431
531
|
return false if @stopped
|
|
432
532
|
return false if @paused.nil?
|
|
433
533
|
|
|
434
|
-
@inventory.count < @inventory.limit *
|
|
534
|
+
@inventory.count < @inventory.limit * UNPAUSE_INVENTORY_RATIO
|
|
435
535
|
end
|
|
436
536
|
|
|
437
537
|
def initial_input_request
|
|
@@ -443,6 +543,7 @@ module Google
|
|
|
443
543
|
req.client_id = @subscriber.service.client_id
|
|
444
544
|
req.max_outstanding_messages = @inventory.limit
|
|
445
545
|
req.max_outstanding_bytes = @inventory.bytesize
|
|
546
|
+
req.protocol_version = PROTOCOL_VERSION
|
|
446
547
|
end
|
|
447
548
|
end
|
|
448
549
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: google-cloud-pubsub
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mike Moore
|
|
@@ -100,6 +100,7 @@ files:
|
|
|
100
100
|
- lib/google/cloud/pubsub/message_listener.rb
|
|
101
101
|
- lib/google/cloud/pubsub/message_listener/enumerator_queue.rb
|
|
102
102
|
- lib/google/cloud/pubsub/message_listener/inventory.rb
|
|
103
|
+
- lib/google/cloud/pubsub/message_listener/keepalive_monitor.rb
|
|
103
104
|
- lib/google/cloud/pubsub/message_listener/sequencer.rb
|
|
104
105
|
- lib/google/cloud/pubsub/message_listener/stream.rb
|
|
105
106
|
- lib/google/cloud/pubsub/message_listener/timed_unary_buffer.rb
|