google-cloud-pubsub 2.22.0 → 3.2.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 +4 -4
- data/AUTHENTICATION.md +12 -1
- data/CHANGELOG.md +69 -0
- data/OVERVIEW.md +189 -145
- data/lib/google/cloud/pubsub/admin_clients.rb +116 -0
- data/lib/google/cloud/pubsub/async_publisher.rb +20 -19
- data/lib/google/cloud/pubsub/batch_publisher.rb +7 -5
- data/lib/google/cloud/pubsub/errors.rb +3 -3
- data/lib/google/cloud/pubsub/internal_logger.rb +76 -0
- data/lib/google/cloud/pubsub/message.rb +8 -8
- data/lib/google/cloud/pubsub/{subscriber → message_listener}/enumerator_queue.rb +1 -1
- data/lib/google/cloud/pubsub/{subscriber → message_listener}/inventory.rb +13 -10
- data/lib/google/cloud/pubsub/{subscriber → message_listener}/sequencer.rb +1 -1
- data/lib/google/cloud/pubsub/{subscriber → message_listener}/stream.rb +61 -18
- data/lib/google/cloud/pubsub/{subscriber → message_listener}/timed_unary_buffer.rb +29 -9
- data/lib/google/cloud/pubsub/message_listener.rb +414 -0
- data/lib/google/cloud/pubsub/project.rb +102 -530
- data/lib/google/cloud/pubsub/publisher.rb +424 -0
- data/lib/google/cloud/pubsub/received_message.rb +50 -45
- data/lib/google/cloud/pubsub/service.rb +34 -385
- data/lib/google/cloud/pubsub/subscriber.rb +442 -279
- data/lib/google/cloud/pubsub/version.rb +1 -1
- data/lib/google/cloud/pubsub.rb +37 -19
- data/lib/google-cloud-pubsub.rb +27 -8
- metadata +19 -26
- data/lib/google/cloud/pubsub/policy.rb +0 -188
- data/lib/google/cloud/pubsub/retry_policy.rb +0 -88
- data/lib/google/cloud/pubsub/schema/list.rb +0 -180
- data/lib/google/cloud/pubsub/schema.rb +0 -378
- data/lib/google/cloud/pubsub/snapshot/list.rb +0 -178
- data/lib/google/cloud/pubsub/snapshot.rb +0 -205
- data/lib/google/cloud/pubsub/subscription/list.rb +0 -205
- data/lib/google/cloud/pubsub/subscription/push_config.rb +0 -268
- data/lib/google/cloud/pubsub/subscription.rb +0 -1467
- data/lib/google/cloud/pubsub/topic/list.rb +0 -171
- data/lib/google/cloud/pubsub/topic.rb +0 -1100
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Copyright 2025 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 "google/cloud/pubsub/v1/topic_admin/client"
|
|
16
|
+
require "google/cloud/pubsub/v1/subscription_admin/client"
|
|
17
|
+
|
|
18
|
+
module Google
|
|
19
|
+
module Cloud
|
|
20
|
+
module PubSub
|
|
21
|
+
module TopicAdmin
|
|
22
|
+
##
|
|
23
|
+
# The TopicAdmin client is used to manage topics.
|
|
24
|
+
#
|
|
25
|
+
# This client is a subclass of the auto-generated TopicAdmin client, and provides
|
|
26
|
+
# the same methods. However, it raises errors on data plane operations
|
|
27
|
+
# to prevent misuse.
|
|
28
|
+
#
|
|
29
|
+
class Client < Google::Cloud::PubSub::V1::TopicAdmin::Client
|
|
30
|
+
# @private
|
|
31
|
+
alias publish_internal publish
|
|
32
|
+
|
|
33
|
+
##
|
|
34
|
+
# The `publish` method is a data plane operation.
|
|
35
|
+
#
|
|
36
|
+
# @raise [NotImplementedError] This method is not implemented on the
|
|
37
|
+
# admin client. Use {Google::Cloud::PubSub::Publisher} instead.
|
|
38
|
+
#
|
|
39
|
+
def publish *args, **kwargs
|
|
40
|
+
raise NotImplementedError,
|
|
41
|
+
"The `publish` method is a data plane operation. " \
|
|
42
|
+
"Use Google::Cloud::PubSub::Publisher instead."
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
module SubscriptionAdmin
|
|
48
|
+
##
|
|
49
|
+
# The SubscriptionAdmin client is used to manage subscriptions.
|
|
50
|
+
#
|
|
51
|
+
# This client is a subclass of the auto-generated SubscriptionAdmin client, and
|
|
52
|
+
# provides the same methods. However, it raises errors on data plane
|
|
53
|
+
# operations to prevent misuse.
|
|
54
|
+
#
|
|
55
|
+
class Client < Google::Cloud::PubSub::V1::SubscriptionAdmin::Client
|
|
56
|
+
# @private
|
|
57
|
+
alias modify_ack_deadline_internal modify_ack_deadline
|
|
58
|
+
# @private
|
|
59
|
+
alias acknowledge_internal acknowledge
|
|
60
|
+
# @private
|
|
61
|
+
alias pull_internal pull
|
|
62
|
+
# @private
|
|
63
|
+
alias streaming_pull_internal streaming_pull
|
|
64
|
+
|
|
65
|
+
##
|
|
66
|
+
# The `modify_ack_deadline` method is a data plane operation.
|
|
67
|
+
#
|
|
68
|
+
# @raise [NotImplementedError] This method is not implemented on the
|
|
69
|
+
# admin client. Use {Google::Cloud::PubSub::Subscriber} instead.
|
|
70
|
+
#
|
|
71
|
+
def modify_ack_deadline *args, **kwargs
|
|
72
|
+
raise NotImplementedError,
|
|
73
|
+
"The `modify_ack_deadline` method is a data plane operation. " \
|
|
74
|
+
"Use Google::Cloud::PubSub::Subscriber instead."
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
##
|
|
78
|
+
# The `acknowledge` method is a data plane operation.
|
|
79
|
+
#
|
|
80
|
+
# @raise [NotImplementedError] This method is not implemented on the
|
|
81
|
+
# admin client. Use {Google::Cloud::PubSub::Subscriber} instead.
|
|
82
|
+
#
|
|
83
|
+
def acknowledge *args, **kwargs
|
|
84
|
+
raise NotImplementedError,
|
|
85
|
+
"The `acknowledge` method is a data plane operation. " \
|
|
86
|
+
"Use Google::Cloud::PubSub::Subscriber instead."
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
##
|
|
90
|
+
# The `pull` method is a data plane operation.
|
|
91
|
+
#
|
|
92
|
+
# @raise [NotImplementedError] This method is not implemented on the
|
|
93
|
+
# admin client. Use {Google::Cloud::PubSub::Subscriber} instead.
|
|
94
|
+
#
|
|
95
|
+
def pull *args, **kwargs
|
|
96
|
+
raise NotImplementedError,
|
|
97
|
+
"The `pull` method is a data plane operation. " \
|
|
98
|
+
"Use Google::Cloud::PubSub::Subscriber instead."
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
##
|
|
102
|
+
# The `streaming_pull` method is a data plane operation.
|
|
103
|
+
#
|
|
104
|
+
# @raise [NotImplementedError] This method is not implemented on the
|
|
105
|
+
# admin client. Use {Google::Cloud::PubSub::Subscriber} instead.
|
|
106
|
+
#
|
|
107
|
+
def streaming_pull *args, **kwargs
|
|
108
|
+
raise NotImplementedError,
|
|
109
|
+
"The `streaming_pull` method is a data plane operation. " \
|
|
110
|
+
"Use Google::Cloud::PubSub::Subscriber instead."
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
@@ -27,15 +27,15 @@ module Google
|
|
|
27
27
|
module PubSub
|
|
28
28
|
##
|
|
29
29
|
# Used to publish multiple messages in batches to a topic. See
|
|
30
|
-
# {Google::Cloud::PubSub::
|
|
30
|
+
# {Google::Cloud::PubSub::Publisher#async_publisher}
|
|
31
31
|
#
|
|
32
32
|
# @example
|
|
33
33
|
# require "google/cloud/pubsub"
|
|
34
34
|
#
|
|
35
35
|
# pubsub = Google::Cloud::PubSub.new
|
|
36
36
|
#
|
|
37
|
-
#
|
|
38
|
-
#
|
|
37
|
+
# publisher = pubsub.publisher "my-topic"
|
|
38
|
+
# publisher.publish_async "task completed" do |result|
|
|
39
39
|
# if result.succeeded?
|
|
40
40
|
# log_publish_success result.data
|
|
41
41
|
# else
|
|
@@ -43,7 +43,7 @@ module Google
|
|
|
43
43
|
# end
|
|
44
44
|
# end
|
|
45
45
|
#
|
|
46
|
-
#
|
|
46
|
+
# publisher.async_publisher.stop!
|
|
47
47
|
#
|
|
48
48
|
# @attr_reader [String] topic_name The name of the topic the messages are published to. The value is a
|
|
49
49
|
# fully-qualified topic name in the form `projects/{project_id}/topics/{topic_id}`.
|
|
@@ -116,7 +116,7 @@ module Google
|
|
|
116
116
|
##
|
|
117
117
|
# Add a message to the async publisher to be published to the topic.
|
|
118
118
|
# Messages will be collected in batches and published together.
|
|
119
|
-
# See {Google::Cloud::PubSub::
|
|
119
|
+
# See {Google::Cloud::PubSub::Publisher#publish_async}
|
|
120
120
|
#
|
|
121
121
|
# @param [String, File] data The message payload. This will be converted
|
|
122
122
|
# to bytes encoded as ASCII-8BIT.
|
|
@@ -157,7 +157,7 @@ module Google
|
|
|
157
157
|
end
|
|
158
158
|
batch_action = batch.add msg, callback
|
|
159
159
|
if batch_action == :full
|
|
160
|
-
publish_batches!
|
|
160
|
+
publish_batches! reason: "batch full"
|
|
161
161
|
elsif @published_at.nil?
|
|
162
162
|
# Set initial time to now to start the background counter
|
|
163
163
|
@published_at = Time.now
|
|
@@ -180,7 +180,7 @@ module Google
|
|
|
180
180
|
break if @stopped
|
|
181
181
|
|
|
182
182
|
@stopped = true
|
|
183
|
-
publish_batches! stop: true
|
|
183
|
+
publish_batches! stop: true, reason: "shutdown"
|
|
184
184
|
@cond.signal
|
|
185
185
|
@publish_thread_pool.shutdown
|
|
186
186
|
end
|
|
@@ -234,7 +234,7 @@ module Google
|
|
|
234
234
|
# @return [AsyncPublisher] returns self so calls can be chained.
|
|
235
235
|
def flush
|
|
236
236
|
synchronize do
|
|
237
|
-
publish_batches!
|
|
237
|
+
publish_batches! reason: "manual flush"
|
|
238
238
|
@cond.signal
|
|
239
239
|
end
|
|
240
240
|
|
|
@@ -262,8 +262,8 @@ module Google
|
|
|
262
262
|
# enabled, messages published with the same `ordering_key` will be
|
|
263
263
|
# delivered in the order they were published.
|
|
264
264
|
#
|
|
265
|
-
# See {#message_ordering?}. See {
|
|
266
|
-
# {
|
|
265
|
+
# See {#message_ordering?}. See {Publisher#publish_async},
|
|
266
|
+
# {Subscriber#listen}, and {Message#ordering_key}.
|
|
267
267
|
#
|
|
268
268
|
def enable_message_ordering!
|
|
269
269
|
synchronize { @ordered = true }
|
|
@@ -275,8 +275,8 @@ module Google
|
|
|
275
275
|
# will be delivered in the order they were published. When disabled,
|
|
276
276
|
# messages may be delivered in any order.
|
|
277
277
|
#
|
|
278
|
-
# See {#enable_message_ordering!}. See {
|
|
279
|
-
# {
|
|
278
|
+
# See {#enable_message_ordering!}. See {Publisher#publish_async},
|
|
279
|
+
# {Subscriber#listen}, and {Message#ordering_key}.
|
|
280
280
|
#
|
|
281
281
|
# @return [Boolean]
|
|
282
282
|
#
|
|
@@ -313,7 +313,7 @@ module Google
|
|
|
313
313
|
time_since_first_publish = Time.now - @published_at
|
|
314
314
|
if time_since_first_publish > @interval
|
|
315
315
|
# interval met, flush the batches...
|
|
316
|
-
publish_batches!
|
|
316
|
+
publish_batches! reason: "interval timeout"
|
|
317
317
|
@cond.wait
|
|
318
318
|
else
|
|
319
319
|
# still waiting for the interval to publish the batch...
|
|
@@ -347,28 +347,28 @@ module Google
|
|
|
347
347
|
end
|
|
348
348
|
end
|
|
349
349
|
|
|
350
|
-
def publish_batches! stop: nil
|
|
350
|
+
def publish_batches! stop: nil, reason: "unknown"
|
|
351
351
|
@batches.reject! { |_ordering_key, batch| batch.empty? }
|
|
352
352
|
@batches.each_value do |batch|
|
|
353
353
|
ready = batch.publish! stop: stop
|
|
354
|
-
publish_batch_async @topic_name, batch if ready
|
|
354
|
+
publish_batch_async @topic_name, batch, reason: reason if ready
|
|
355
355
|
end
|
|
356
356
|
# Set published_at to nil to wait indefinitely
|
|
357
357
|
@published_at = nil
|
|
358
358
|
end
|
|
359
359
|
|
|
360
|
-
def publish_batch_async topic_name, batch
|
|
360
|
+
def publish_batch_async topic_name, batch, reason: "unknown"
|
|
361
361
|
# TODO: raise unless @publish_thread_pool.running?
|
|
362
362
|
return unless @publish_thread_pool.running?
|
|
363
363
|
|
|
364
364
|
Concurrent::Promises.future_on(
|
|
365
|
-
@publish_thread_pool, topic_name, batch
|
|
366
|
-
) { |t, b| publish_batch_sync t, b }
|
|
365
|
+
@publish_thread_pool, topic_name, batch, reason
|
|
366
|
+
) { |t, b, r| publish_batch_sync t, b, reason: r }
|
|
367
367
|
end
|
|
368
368
|
|
|
369
369
|
# rubocop:disable Metrics/AbcSize
|
|
370
370
|
|
|
371
|
-
def publish_batch_sync topic_name, batch
|
|
371
|
+
def publish_batch_sync topic_name, batch, reason: "unknown"
|
|
372
372
|
# The only batch methods that are safe to call from the loop are
|
|
373
373
|
# rebalance! and reset! because they are the only methods that are
|
|
374
374
|
# synchronized.
|
|
@@ -379,6 +379,7 @@ module Google
|
|
|
379
379
|
grpc = @service.publish topic_name,
|
|
380
380
|
items.map(&:msg),
|
|
381
381
|
compress: compress && batch.total_message_bytes >= compression_bytes_threshold
|
|
382
|
+
service.logger.log_batch "publish-batch", reason, "publish", items.count, items.sum(&:bytesize)
|
|
382
383
|
items.zip Array(grpc.message_ids) do |item, id|
|
|
383
384
|
@flow_controller.release item.bytesize
|
|
384
385
|
next unless item.callback
|
|
@@ -27,14 +27,15 @@ module Google
|
|
|
27
27
|
#
|
|
28
28
|
# pubsub = Google::Cloud::PubSub.new
|
|
29
29
|
#
|
|
30
|
-
#
|
|
31
|
-
# msgs =
|
|
30
|
+
# publisher = pubsub.publisher "my-topic"
|
|
31
|
+
# msgs = publisher.publish do |batch_publisher|
|
|
32
32
|
# batch_publisher.publish "task 1 completed", foo: :bar
|
|
33
33
|
# batch_publisher.publish "task 2 completed", foo: :baz
|
|
34
34
|
# batch_publisher.publish "task 3 completed", foo: :bif
|
|
35
35
|
# end
|
|
36
36
|
#
|
|
37
37
|
class BatchPublisher
|
|
38
|
+
|
|
38
39
|
##
|
|
39
40
|
# @private The messages to publish
|
|
40
41
|
attr_reader :messages
|
|
@@ -86,8 +87,8 @@ module Google
|
|
|
86
87
|
#
|
|
87
88
|
# pubsub = Google::Cloud::PubSub.new
|
|
88
89
|
#
|
|
89
|
-
#
|
|
90
|
-
# msgs =
|
|
90
|
+
# publisher = pubsub.publisher "my-topic"
|
|
91
|
+
# msgs = publisher.publish do |batch_publisher|
|
|
91
92
|
# batch_publisher.publish "task 1 completed", foo: :bar
|
|
92
93
|
# batch_publisher.publish "task 2 completed", foo: :baz
|
|
93
94
|
# batch_publisher.publish "task 3 completed", foo: :bif
|
|
@@ -117,10 +118,11 @@ module Google
|
|
|
117
118
|
|
|
118
119
|
##
|
|
119
120
|
# @private Call the publish API with arrays of data and attrs.
|
|
120
|
-
def publish_batch_messages topic_name, service
|
|
121
|
+
def publish_batch_messages topic_name, service, reason: "unknown"
|
|
121
122
|
grpc = service.publish topic_name,
|
|
122
123
|
messages,
|
|
123
124
|
compress: compress && total_message_bytes >= compression_bytes_threshold
|
|
125
|
+
service.logger.log_batch "publish-batch", reason, "publish", messages.count, @total_message_bytes
|
|
124
126
|
to_gcloud_messages Array(grpc.message_ids)
|
|
125
127
|
end
|
|
126
128
|
end
|
|
@@ -41,7 +41,7 @@ module Google
|
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
##
|
|
44
|
-
# Indicates that the {
|
|
44
|
+
# Indicates that the {MessageListener} for a {Subscriber} with message
|
|
45
45
|
# ordering enabled has observed that a message has been delivered out of
|
|
46
46
|
# order.
|
|
47
47
|
#
|
|
@@ -57,11 +57,11 @@ module Google
|
|
|
57
57
|
|
|
58
58
|
##
|
|
59
59
|
# Indicates that messages using the {#ordering_key} are not being
|
|
60
|
-
# published due to error. Future calls to {
|
|
60
|
+
# published due to error. Future calls to {Publisher#publish_async} with the
|
|
61
61
|
# {#ordering_key} will fail with this error.
|
|
62
62
|
#
|
|
63
63
|
# To allow future messages with the {#ordering_key} to be published, the
|
|
64
|
-
# {#ordering_key} must be passed to {
|
|
64
|
+
# {#ordering_key} must be passed to {Publisher#resume_publish}.
|
|
65
65
|
#
|
|
66
66
|
# If this error is retrieved from {PublishResult#error}, inspect `cause`
|
|
67
67
|
# for the error raised while publishing.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Copyright 2025 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
|
+
require "logger"
|
|
15
|
+
|
|
16
|
+
require "google/cloud/config"
|
|
17
|
+
|
|
18
|
+
module Google
|
|
19
|
+
module Cloud
|
|
20
|
+
module PubSub
|
|
21
|
+
##
|
|
22
|
+
# @private
|
|
23
|
+
class InternalLogger
|
|
24
|
+
LOG_NAME = "pubsub".freeze
|
|
25
|
+
VALID_LOG_LEVELS = [:debug, :info, :warn, :error, :fatal].freeze
|
|
26
|
+
private_constant :VALID_LOG_LEVELS, :LOG_NAME
|
|
27
|
+
|
|
28
|
+
##
|
|
29
|
+
# @private
|
|
30
|
+
# rubocop:disable Naming/BlockForwarding
|
|
31
|
+
def log level, subtag, &message_block
|
|
32
|
+
return unless VALID_LOG_LEVELS.include?(level) && block_given?
|
|
33
|
+
# Only log if the logger is explicitly tagged for 'pubsub'.
|
|
34
|
+
return unless @logger && @logger.progname == LOG_NAME
|
|
35
|
+
|
|
36
|
+
@logger.public_send(level, "#{LOG_NAME}:#{subtag}", &message_block)
|
|
37
|
+
end
|
|
38
|
+
# rubocop:enable Naming/BlockForwarding
|
|
39
|
+
|
|
40
|
+
##
|
|
41
|
+
# @private
|
|
42
|
+
def log_batch logger_name, reason, type, num_messages, total_bytes
|
|
43
|
+
log :info, logger_name do
|
|
44
|
+
"#{reason} triggered #{type} batch of #{num_messages} messages, a total of #{total_bytes} bytes"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
##
|
|
49
|
+
# @private
|
|
50
|
+
def log_ack_nack ack_ids, type
|
|
51
|
+
ack_ids.each do |ack_id|
|
|
52
|
+
log :info, "ack-nack" do
|
|
53
|
+
"message (ackID #{ack_id}) #{type}"
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
##
|
|
59
|
+
# @private
|
|
60
|
+
def log_expiry expired
|
|
61
|
+
expired.each do |ack_id, item|
|
|
62
|
+
log :info, "expiry" do
|
|
63
|
+
"message (ID #{item.message_id}, ackID #{ack_id}) has been dropped from leasing due to a timeout"
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
|
|
70
|
+
def initialize logger
|
|
71
|
+
@logger = logger || Logger.new(nil)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -24,7 +24,7 @@ module Google
|
|
|
24
24
|
#
|
|
25
25
|
# Represents a Pub/Sub Message.
|
|
26
26
|
#
|
|
27
|
-
# Message objects are created by {
|
|
27
|
+
# Message objects are created by {Publisher#publish}. {Subscriber#pull}
|
|
28
28
|
# returns an array of {ReceivedMessage} objects, each of which contains a
|
|
29
29
|
# Message object. Each {ReceivedMessage} object can be acknowledged and/or
|
|
30
30
|
# delayed.
|
|
@@ -35,22 +35,22 @@ module Google
|
|
|
35
35
|
# pubsub = Google::Cloud::PubSub.new
|
|
36
36
|
#
|
|
37
37
|
# # Publish a message
|
|
38
|
-
#
|
|
39
|
-
# message =
|
|
38
|
+
# publisher = pubsub.publisher "my-topic"
|
|
39
|
+
# message = publisher.publish "task completed"
|
|
40
40
|
# message.data #=> "task completed"
|
|
41
41
|
#
|
|
42
42
|
# # Listen for messages
|
|
43
|
-
#
|
|
44
|
-
#
|
|
43
|
+
# subscriber = pubsub.subscriber "my-topic-sub"
|
|
44
|
+
# listener = subscriber.listen do |received_message|
|
|
45
45
|
# # process message
|
|
46
46
|
# received_message.acknowledge!
|
|
47
47
|
# end
|
|
48
48
|
#
|
|
49
49
|
# # Start background threads that will call the block passed to listen.
|
|
50
|
-
#
|
|
50
|
+
# listener.start
|
|
51
51
|
#
|
|
52
52
|
# # Shut down the subscriber when ready to stop receiving messages.
|
|
53
|
-
#
|
|
53
|
+
# listener.stop!
|
|
54
54
|
#
|
|
55
55
|
class Message
|
|
56
56
|
##
|
|
@@ -113,7 +113,7 @@ module Google
|
|
|
113
113
|
# or scalability, as the service automatically distributes messages for
|
|
114
114
|
# different ordering keys across subscribers.
|
|
115
115
|
#
|
|
116
|
-
# See {
|
|
116
|
+
# See {Publisher#publish_async} and {Subscriber#listen}.
|
|
117
117
|
#
|
|
118
118
|
# @return [String]
|
|
119
119
|
#
|
|
@@ -12,19 +12,18 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
-
|
|
16
15
|
require "monitor"
|
|
17
16
|
|
|
18
17
|
module Google
|
|
19
18
|
module Cloud
|
|
20
19
|
module PubSub
|
|
21
|
-
class
|
|
20
|
+
class MessageListener
|
|
22
21
|
##
|
|
23
22
|
# @private
|
|
24
23
|
class Inventory
|
|
25
|
-
InventoryItem = Struct.new :bytesize, :pulled_at do
|
|
24
|
+
InventoryItem = Struct.new :message_id, :bytesize, :pulled_at do
|
|
26
25
|
def self.from rec_msg
|
|
27
|
-
new rec_msg.to_proto.bytesize, Time.now
|
|
26
|
+
new rec_msg.message.message_id, rec_msg.to_proto.bytesize, Time.now
|
|
28
27
|
end
|
|
29
28
|
end
|
|
30
29
|
|
|
@@ -36,10 +35,9 @@ module Google
|
|
|
36
35
|
attr_reader :extension
|
|
37
36
|
attr_reader :max_duration_per_lease_extension
|
|
38
37
|
attr_accessor :min_duration_per_lease_extension
|
|
39
|
-
attr_reader :use_legacy_flow_control
|
|
40
38
|
|
|
41
39
|
def initialize stream, limit:, bytesize:, extension:, max_duration_per_lease_extension:,
|
|
42
|
-
min_duration_per_lease_extension
|
|
40
|
+
min_duration_per_lease_extension:
|
|
43
41
|
super()
|
|
44
42
|
@stream = stream
|
|
45
43
|
@limit = limit
|
|
@@ -47,7 +45,6 @@ module Google
|
|
|
47
45
|
@extension = extension
|
|
48
46
|
@max_duration_per_lease_extension = max_duration_per_lease_extension
|
|
49
47
|
@min_duration_per_lease_extension = min_duration_per_lease_extension
|
|
50
|
-
@use_legacy_flow_control = use_legacy_flow_control
|
|
51
48
|
@inventory = {}
|
|
52
49
|
@wait_cond = new_cond
|
|
53
50
|
end
|
|
@@ -72,18 +69,24 @@ module Google
|
|
|
72
69
|
def remove *ack_ids
|
|
73
70
|
ack_ids.flatten!
|
|
74
71
|
ack_ids.compact!
|
|
75
|
-
return if ack_ids.empty?
|
|
72
|
+
return {} if ack_ids.empty?
|
|
76
73
|
|
|
74
|
+
removed_items = {}
|
|
77
75
|
synchronize do
|
|
78
|
-
@inventory.
|
|
76
|
+
removed, keep = @inventory.partition { |ack_id, _| ack_ids.include? ack_id }
|
|
77
|
+
@inventory = keep.to_h
|
|
78
|
+
removed_items = removed.to_h
|
|
79
79
|
@wait_cond.broadcast
|
|
80
80
|
end
|
|
81
|
+
removed_items
|
|
81
82
|
end
|
|
82
83
|
|
|
83
84
|
def remove_expired!
|
|
84
85
|
synchronize do
|
|
85
86
|
extension_time = Time.new - extension
|
|
86
|
-
@inventory.
|
|
87
|
+
expired, keep = @inventory.partition { |_ack_id, item| item.pulled_at < extension_time }
|
|
88
|
+
@inventory = keep.to_h
|
|
89
|
+
stream.subscriber.service.logger.log_expiry expired
|
|
87
90
|
@wait_cond.broadcast
|
|
88
91
|
end
|
|
89
92
|
end
|