google-cloud-pubsub 1.0.2 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -0
- data/CONTRIBUTING.md +1 -1
- data/OVERVIEW.md +83 -1
- data/lib/google-cloud-pubsub.rb +6 -14
- data/lib/google/cloud/pubsub.rb +5 -12
- data/lib/google/cloud/pubsub/async_publisher.rb +164 -132
- data/lib/google/cloud/pubsub/async_publisher/batch.rb +309 -0
- data/lib/google/cloud/pubsub/batch_publisher.rb +2 -4
- data/lib/google/cloud/pubsub/convert.rb +33 -7
- data/lib/google/cloud/pubsub/errors.rb +85 -0
- data/lib/google/cloud/pubsub/message.rb +42 -0
- data/lib/google/cloud/pubsub/project.rb +2 -5
- data/lib/google/cloud/pubsub/publish_result.rb +6 -1
- data/lib/google/cloud/pubsub/received_message.rb +42 -0
- data/lib/google/cloud/pubsub/service.rb +11 -18
- data/lib/google/cloud/pubsub/snapshot/list.rb +2 -4
- data/lib/google/cloud/pubsub/subscriber.rb +9 -5
- data/lib/google/cloud/pubsub/subscriber/inventory.rb +14 -16
- data/lib/google/cloud/pubsub/subscriber/sequencer.rb +115 -0
- data/lib/google/cloud/pubsub/subscriber/stream.rb +50 -26
- data/lib/google/cloud/pubsub/subscriber/timed_unary_buffer.rb +10 -15
- data/lib/google/cloud/pubsub/subscription.rb +90 -29
- data/lib/google/cloud/pubsub/subscription/list.rb +2 -4
- data/lib/google/cloud/pubsub/topic.rb +109 -17
- data/lib/google/cloud/pubsub/topic/list.rb +2 -4
- data/lib/google/cloud/pubsub/version.rb +1 -1
- metadata +39 -36
@@ -13,6 +13,7 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
|
16
|
+
require "google/cloud/pubsub/subscriber/sequencer"
|
16
17
|
require "google/cloud/pubsub/subscriber/enumerator_queue"
|
17
18
|
require "google/cloud/pubsub/subscriber/inventory"
|
18
19
|
require "google/cloud/pubsub/service"
|
@@ -34,9 +35,17 @@ module Google
|
|
34
35
|
attr_reader :callback_thread_pool
|
35
36
|
|
36
37
|
##
|
37
|
-
# Subscriber attributes.
|
38
|
+
# @private Subscriber attributes.
|
38
39
|
attr_reader :subscriber
|
39
40
|
|
41
|
+
##
|
42
|
+
# @private Inventory.
|
43
|
+
attr_reader :inventory
|
44
|
+
|
45
|
+
##
|
46
|
+
# @private Sequencer.
|
47
|
+
attr_reader :sequencer
|
48
|
+
|
40
49
|
##
|
41
50
|
# @private Create an empty Subscriber::Stream object.
|
42
51
|
def initialize subscriber
|
@@ -48,16 +57,16 @@ module Google
|
|
48
57
|
@pause_cond = new_cond
|
49
58
|
|
50
59
|
@inventory = Inventory.new self, @subscriber.stream_inventory
|
51
|
-
|
52
|
-
|
60
|
+
|
61
|
+
@sequencer = Sequencer.new(&method(:perform_callback_async)) if subscriber.message_ordering
|
62
|
+
|
63
|
+
@callback_thread_pool = Concurrent::ThreadPoolExecutor.new max_threads: @subscriber.callback_threads
|
53
64
|
|
54
65
|
@stream_keepalive_task = Concurrent::TimerTask.new(
|
55
66
|
execution_interval: 30
|
56
67
|
) do
|
57
68
|
# push empty request every 30 seconds to keep stream alive
|
58
|
-
unless inventory.empty?
|
59
|
-
push Google::Cloud::PubSub::V1::StreamingPullRequest.new
|
60
|
-
end
|
69
|
+
push Google::Cloud::PubSub::V1::StreamingPullRequest.new unless inventory.empty?
|
61
70
|
end.execute
|
62
71
|
|
63
72
|
super() # to init MonitorMixin
|
@@ -81,7 +90,7 @@ module Google
|
|
81
90
|
|
82
91
|
# Close the stream by pushing the sentinel value.
|
83
92
|
# The unary pusher does not use the stream, so it can close here.
|
84
|
-
@request_queue
|
93
|
+
@request_queue&.push self
|
85
94
|
|
86
95
|
# Signal to the background thread that we are stopped.
|
87
96
|
@stopped = true
|
@@ -107,6 +116,10 @@ module Google
|
|
107
116
|
synchronize { @paused }
|
108
117
|
end
|
109
118
|
|
119
|
+
def running?
|
120
|
+
!stopped?
|
121
|
+
end
|
122
|
+
|
110
123
|
def wait! timeout = nil
|
111
124
|
# Wait for all queued callbacks to be processed.
|
112
125
|
@callback_thread_pool.wait_for_termination timeout
|
@@ -162,10 +175,6 @@ module Google
|
|
162
175
|
synchronize { @request_queue.push request }
|
163
176
|
end
|
164
177
|
|
165
|
-
def inventory
|
166
|
-
synchronize { @inventory }
|
167
|
-
end
|
168
|
-
|
169
178
|
##
|
170
179
|
# @private
|
171
180
|
def renew_lease!
|
@@ -182,8 +191,8 @@ module Google
|
|
182
191
|
|
183
192
|
# @private
|
184
193
|
def to_s
|
185
|
-
"
|
186
|
-
|
194
|
+
seq_str = "sequenced: #{sequencer}, " if sequencer
|
195
|
+
"(inventory: #{@inventory.count}, #{seq_str}status: #{status}, thread: #{thread_status})"
|
187
196
|
end
|
188
197
|
|
189
198
|
# @private
|
@@ -237,6 +246,7 @@ module Google
|
|
237
246
|
# Create a list of all the received ack_id values
|
238
247
|
received_ack_ids = response.received_messages.map(&:ack_id)
|
239
248
|
|
249
|
+
# Use synchronize so both changes happen atomically
|
240
250
|
synchronize do
|
241
251
|
# Create receipt of received messages reception
|
242
252
|
@subscriber.buffer.modify_ack_deadline @subscriber.deadline,
|
@@ -248,10 +258,8 @@ module Google
|
|
248
258
|
|
249
259
|
response.received_messages.each do |rec_msg_grpc|
|
250
260
|
rec_msg = ReceivedMessage.from_grpc(rec_msg_grpc, self)
|
251
|
-
synchronize
|
252
|
-
|
253
|
-
perform_callback_async rec_msg
|
254
|
-
end
|
261
|
+
# No need to synchronize the callback future
|
262
|
+
register_callback rec_msg
|
255
263
|
end
|
256
264
|
synchronize { pause_streaming! }
|
257
265
|
rescue StopIteration
|
@@ -282,18 +290,35 @@ module Google
|
|
282
290
|
|
283
291
|
# rubocop:enable all
|
284
292
|
|
293
|
+
def register_callback rec_msg
|
294
|
+
if @sequencer
|
295
|
+
# Add the message to the sequencer to invoke the callback.
|
296
|
+
@sequencer.add rec_msg
|
297
|
+
else
|
298
|
+
# Call user provided code for received message
|
299
|
+
perform_callback_async rec_msg
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
285
303
|
def perform_callback_async rec_msg
|
286
304
|
return unless callback_thread_pool.running?
|
287
305
|
|
288
306
|
Concurrent::Promises.future_on(
|
289
|
-
callback_thread_pool,
|
290
|
-
)
|
307
|
+
callback_thread_pool, rec_msg, &method(:perform_callback_sync)
|
308
|
+
)
|
309
|
+
end
|
310
|
+
|
311
|
+
def perform_callback_sync rec_msg
|
312
|
+
@subscriber.callback.call rec_msg unless stopped?
|
313
|
+
rescue StandardError => e
|
314
|
+
@subscriber.error! e
|
315
|
+
ensure
|
316
|
+
release rec_msg
|
317
|
+
if @sequencer && running?
|
291
318
|
begin
|
292
|
-
|
293
|
-
rescue
|
294
|
-
|
295
|
-
ensure
|
296
|
-
stream.release msg
|
319
|
+
@sequencer.next rec_msg
|
320
|
+
rescue OrderedMessageDeliveryError => e
|
321
|
+
@subscriber.error! e
|
297
322
|
end
|
298
323
|
end
|
299
324
|
end
|
@@ -341,8 +366,7 @@ module Google
|
|
341
366
|
req.subscription = @subscriber.subscription_name
|
342
367
|
req.stream_ack_deadline_seconds = @subscriber.deadline
|
343
368
|
req.modify_deadline_ack_ids += @inventory.ack_ids
|
344
|
-
req.modify_deadline_seconds +=
|
345
|
-
@inventory.ack_ids.map { @subscriber.deadline }
|
369
|
+
req.modify_deadline_seconds += @inventory.ack_ids.map { @subscriber.deadline }
|
346
370
|
end
|
347
371
|
end
|
348
372
|
|
@@ -27,7 +27,7 @@ module Google
|
|
27
27
|
|
28
28
|
attr_reader :max_bytes, :interval
|
29
29
|
|
30
|
-
def initialize subscriber, max_bytes:
|
30
|
+
def initialize subscriber, max_bytes: 500_000, interval: 1.0
|
31
31
|
super() # to init MonitorMixin
|
32
32
|
|
33
33
|
@subscriber = subscriber
|
@@ -91,15 +91,13 @@ module Google
|
|
91
91
|
with_threadpool do |pool|
|
92
92
|
requests[:acknowledge].each do |ack_req|
|
93
93
|
add_future pool do
|
94
|
-
@subscriber.service.acknowledge
|
95
|
-
ack_req.subscription, *ack_req.ack_ids
|
94
|
+
@subscriber.service.acknowledge ack_req.subscription, *ack_req.ack_ids
|
96
95
|
end
|
97
96
|
end
|
98
97
|
requests[:modify_ack_deadline].each do |mod_ack_req|
|
99
98
|
add_future pool do
|
100
|
-
@subscriber.service.modify_ack_deadline
|
101
|
-
|
102
|
-
mod_ack_req.ack_deadline_seconds
|
99
|
+
@subscriber.service.modify_ack_deadline mod_ack_req.subscription, mod_ack_req.ack_ids,
|
100
|
+
mod_ack_req.ack_deadline_seconds
|
103
101
|
end
|
104
102
|
end
|
105
103
|
end
|
@@ -144,9 +142,7 @@ module Google
|
|
144
142
|
|
145
143
|
requests = { acknowledge: [] }
|
146
144
|
ack_ids = Array(req_hash.delete(:ack)) # ack has no deadline set
|
147
|
-
if ack_ids.any?
|
148
|
-
requests[:acknowledge] = create_acknowledge_requests ack_ids
|
149
|
-
end
|
145
|
+
requests[:acknowledge] = create_acknowledge_requests ack_ids if ack_ids.any?
|
150
146
|
requests[:modify_ack_deadline] =
|
151
147
|
req_hash.map do |mod_deadline, mod_ack_ids|
|
152
148
|
create_modify_ack_deadline_requests mod_deadline, mod_ack_ids
|
@@ -201,8 +197,7 @@ module Google
|
|
201
197
|
end
|
202
198
|
|
203
199
|
def with_threadpool
|
204
|
-
pool = Concurrent::ThreadPoolExecutor.new
|
205
|
-
max_threads: @subscriber.push_threads
|
200
|
+
pool = Concurrent::ThreadPoolExecutor.new max_threads: @subscriber.push_threads
|
206
201
|
|
207
202
|
yield pool
|
208
203
|
|
@@ -213,8 +208,8 @@ module Google
|
|
213
208
|
pool.kill
|
214
209
|
begin
|
215
210
|
raise "Timeout making subscriber API calls"
|
216
|
-
rescue StandardError =>
|
217
|
-
error!
|
211
|
+
rescue StandardError => e
|
212
|
+
error! e
|
218
213
|
end
|
219
214
|
end
|
220
215
|
|
@@ -222,8 +217,8 @@ module Google
|
|
222
217
|
Concurrent::Promises.future_on pool do
|
223
218
|
begin
|
224
219
|
yield
|
225
|
-
rescue StandardError =>
|
226
|
-
error!
|
220
|
+
rescue StandardError => e
|
221
|
+
error! e
|
227
222
|
end
|
228
223
|
end
|
229
224
|
end
|
@@ -117,10 +117,8 @@ module Google
|
|
117
117
|
# @param [Integer] new_deadline The new deadline value.
|
118
118
|
#
|
119
119
|
def deadline= new_deadline
|
120
|
-
update_grpc = Google::Cloud::PubSub::V1::Subscription.new
|
121
|
-
|
122
|
-
@grpc = service.update_subscription update_grpc,
|
123
|
-
:ack_deadline_seconds
|
120
|
+
update_grpc = Google::Cloud::PubSub::V1::Subscription.new name: name, ack_deadline_seconds: new_deadline
|
121
|
+
@grpc = service.update_subscription update_grpc, :ack_deadline_seconds
|
124
122
|
@resource_name = nil
|
125
123
|
end
|
126
124
|
|
@@ -148,10 +146,9 @@ module Google
|
|
148
146
|
# value.
|
149
147
|
#
|
150
148
|
def retain_acked= new_retain_acked
|
151
|
-
update_grpc = Google::Cloud::PubSub::V1::Subscription.new
|
152
|
-
|
153
|
-
@grpc = service.update_subscription update_grpc,
|
154
|
-
:retain_acked_messages
|
149
|
+
update_grpc = Google::Cloud::PubSub::V1::Subscription.new name: name,
|
150
|
+
retain_acked_messages: !(!new_retain_acked)
|
151
|
+
@grpc = service.update_subscription update_grpc, :retain_acked_messages
|
155
152
|
@resource_name = nil
|
156
153
|
end
|
157
154
|
|
@@ -181,10 +178,9 @@ module Google
|
|
181
178
|
#
|
182
179
|
def retention= new_retention
|
183
180
|
new_retention_duration = Convert.number_to_duration new_retention
|
184
|
-
update_grpc = Google::Cloud::PubSub::V1::Subscription.new
|
185
|
-
|
186
|
-
@grpc = service.update_subscription update_grpc,
|
187
|
-
:message_retention_duration
|
181
|
+
update_grpc = Google::Cloud::PubSub::V1::Subscription.new name: name,
|
182
|
+
message_retention_duration: new_retention_duration
|
183
|
+
@grpc = service.update_subscription update_grpc, :message_retention_duration
|
188
184
|
@resource_name = nil
|
189
185
|
end
|
190
186
|
|
@@ -200,7 +196,7 @@ module Google
|
|
200
196
|
#
|
201
197
|
def endpoint
|
202
198
|
ensure_grpc!
|
203
|
-
@grpc.push_config
|
199
|
+
@grpc.push_config&.push_endpoint
|
204
200
|
end
|
205
201
|
|
206
202
|
##
|
@@ -271,8 +267,7 @@ module Google
|
|
271
267
|
new_config = config.to_grpc
|
272
268
|
|
273
269
|
if old_config != new_config # has the object been changed?
|
274
|
-
update_grpc = Google::Cloud::PubSub::V1::Subscription.new
|
275
|
-
name: name, push_config: new_config
|
270
|
+
update_grpc = Google::Cloud::PubSub::V1::Subscription.new name: name, push_config: new_config
|
276
271
|
@grpc = service.update_subscription update_grpc, :push_config
|
277
272
|
end
|
278
273
|
end
|
@@ -312,8 +307,7 @@ module Google
|
|
312
307
|
#
|
313
308
|
def labels= new_labels
|
314
309
|
raise ArgumentError, "Value must be a Hash" if new_labels.nil?
|
315
|
-
update_grpc = Google::Cloud::PubSub::V1::Subscription.new
|
316
|
-
name: name, labels: new_labels
|
310
|
+
update_grpc = Google::Cloud::PubSub::V1::Subscription.new name: name, labels: new_labels
|
317
311
|
@grpc = service.update_subscription update_grpc, :labels
|
318
312
|
@resource_name = nil
|
319
313
|
end
|
@@ -350,16 +344,34 @@ module Google
|
|
350
344
|
# to unset.
|
351
345
|
#
|
352
346
|
def expires_in= ttl
|
353
|
-
new_expiration_policy = Google::Pubsub::V1::ExpirationPolicy.new(
|
354
|
-
ttl: Convert.number_to_duration(ttl)
|
355
|
-
)
|
347
|
+
new_expiration_policy = Google::Pubsub::V1::ExpirationPolicy.new ttl: Convert.number_to_duration(ttl)
|
356
348
|
|
357
|
-
update_grpc = Google::Cloud::PubSub::V1::Subscription.new
|
358
|
-
name: name, expiration_policy: new_expiration_policy
|
349
|
+
update_grpc = Google::Cloud::PubSub::V1::Subscription.new name: name, expiration_policy: new_expiration_policy
|
359
350
|
@grpc = service.update_subscription update_grpc, :expiration_policy
|
360
351
|
@resource_name = nil
|
361
352
|
end
|
362
353
|
|
354
|
+
##
|
355
|
+
# Whether message ordering has been enabled. When enabled, messages
|
356
|
+
# published with the same `ordering_key` will be delivered in the order
|
357
|
+
# they were published. When disabled, messages may be delivered in any
|
358
|
+
# order.
|
359
|
+
#
|
360
|
+
# @note At the time of this release, ordering keys are not yet publicly
|
361
|
+
# enabled and requires special project enablements.
|
362
|
+
#
|
363
|
+
# See {Topic#publish_async}, {#listen}, and {Message#ordering_key}.
|
364
|
+
#
|
365
|
+
# Makes an API call to retrieve the retain_acked value when called on a
|
366
|
+
# reference object. See {#reference?}.
|
367
|
+
#
|
368
|
+
# @return [Boolean]
|
369
|
+
#
|
370
|
+
def message_ordering?
|
371
|
+
ensure_grpc!
|
372
|
+
@grpc.enable_message_ordering
|
373
|
+
end
|
374
|
+
|
363
375
|
##
|
364
376
|
# Determines whether the subscription exists in the Pub/Sub service.
|
365
377
|
#
|
@@ -508,13 +520,40 @@ module Google
|
|
508
520
|
# message will be removed from the subscriber and made available for
|
509
521
|
# redelivery after the callback is completed.
|
510
522
|
#
|
523
|
+
# Google Cloud Pub/Sub ordering keys provide the ability to ensure
|
524
|
+
# related messages are sent to subscribers in the order in which they
|
525
|
+
# were published. Messages can be tagged with an ordering key, a string
|
526
|
+
# that identifies related messages for which publish order should be
|
527
|
+
# respected. The service guarantees that, for a given ordering key and
|
528
|
+
# publisher, messages are sent to subscribers in the order in which they
|
529
|
+
# were published. Ordering does not require sacrificing high throughput
|
530
|
+
# or scalability, as the service automatically distributes messages for
|
531
|
+
# different ordering keys across subscribers.
|
532
|
+
#
|
533
|
+
# To use ordering keys, the subscription must be created with message
|
534
|
+
# ordering enabled (See {Topic#subscribe} and {#message_ordering?})
|
535
|
+
# before calling {#listen}. When enabled, the subscriber will deliver
|
536
|
+
# messages with the same `ordering_key` in the order they were
|
537
|
+
# published.
|
538
|
+
#
|
539
|
+
# @note At the time of this release, ordering keys are not yet publicly
|
540
|
+
# enabled and requires special project enablements.
|
541
|
+
#
|
511
542
|
# @param [Numeric] deadline The default number of seconds the stream
|
512
543
|
# will hold received messages before modifying the message's ack
|
513
544
|
# deadline. The minimum is 10, the maximum is 600. Default is
|
514
545
|
# {#deadline}. Optional.
|
515
546
|
#
|
516
|
-
#
|
517
|
-
#
|
547
|
+
# When using a reference object an API call will be made to retrieve
|
548
|
+
# the default deadline value for the subscription when this argument
|
549
|
+
# is not provided. See {#reference?}.
|
550
|
+
# @param [Boolean] message_ordering Whether message ordering has been
|
551
|
+
# enabled. The value provided must match the value set on the Pub/Sub
|
552
|
+
# service. See {#message_ordering?}. Optional.
|
553
|
+
#
|
554
|
+
# When using a reference object an API call will be made to retrieve
|
555
|
+
# the default message_ordering value for the subscription when this
|
556
|
+
# argument is not provided. See {#reference?}.
|
518
557
|
# @param [Integer] streams The number of concurrent streams to open to
|
519
558
|
# pull messages from the subscription. Default is 4. Optional.
|
520
559
|
# @param [Integer] inventory The number of received messages to be
|
@@ -571,14 +610,36 @@ module Google
|
|
571
610
|
# # Start background threads that will call block passed to listen.
|
572
611
|
# subscriber.start
|
573
612
|
#
|
574
|
-
|
575
|
-
|
613
|
+
# # Shut down the subscriber when ready to stop receiving messages.
|
614
|
+
# subscriber.stop.wait!
|
615
|
+
#
|
616
|
+
# @example Ordered messages are supported using ordering_key:
|
617
|
+
# require "google/cloud/pubsub"
|
618
|
+
#
|
619
|
+
# pubsub = Google::Cloud::PubSub.new
|
620
|
+
#
|
621
|
+
# sub = pubsub.subscription "my-ordered-topic-sub"
|
622
|
+
# sub.message_ordering? #=> true
|
623
|
+
#
|
624
|
+
# subscriber = sub.listen do |received_message|
|
625
|
+
# # messsages with the same ordering_key are received
|
626
|
+
# # in the order in which they were published.
|
627
|
+
# received_message.acknowledge!
|
628
|
+
# end
|
629
|
+
#
|
630
|
+
# # Start background threads that will call block passed to listen.
|
631
|
+
# subscriber.start
|
632
|
+
#
|
633
|
+
# # Shut down the subscriber when ready to stop receiving messages.
|
634
|
+
# subscriber.stop.wait!
|
635
|
+
#
|
636
|
+
def listen deadline: nil, message_ordering: nil, streams: nil, inventory: nil, threads: {}, &block
|
576
637
|
ensure_service!
|
577
638
|
deadline ||= self.deadline
|
639
|
+
message_ordering = message_ordering? if message_ordering.nil?
|
578
640
|
|
579
|
-
Subscriber.new name, block, deadline: deadline, streams: streams,
|
580
|
-
|
581
|
-
service: service
|
641
|
+
Subscriber.new name, block, deadline: deadline, streams: streams, inventory: inventory,
|
642
|
+
message_ordering: message_ordering, threads: threads, service: service
|
582
643
|
end
|
583
644
|
|
584
645
|
##
|
@@ -132,15 +132,13 @@ module Google
|
|
132
132
|
#
|
133
133
|
def all request_limit: nil
|
134
134
|
request_limit = request_limit.to_i if request_limit
|
135
|
-
unless block_given?
|
136
|
-
return enum_for :all, request_limit: request_limit
|
137
|
-
end
|
135
|
+
return enum_for :all, request_limit: request_limit unless block_given?
|
138
136
|
results = self
|
139
137
|
loop do
|
140
138
|
results.each { |r| yield r }
|
141
139
|
if request_limit
|
142
140
|
request_limit -= 1
|
143
|
-
break if request_limit
|
141
|
+
break if request_limit.negative?
|
144
142
|
end
|
145
143
|
break unless results.next?
|
146
144
|
results = results.next
|
@@ -126,8 +126,7 @@ module Google
|
|
126
126
|
#
|
127
127
|
def labels= new_labels
|
128
128
|
raise ArgumentError, "Value must be a Hash" if new_labels.nil?
|
129
|
-
update_grpc = Google::Cloud::PubSub::V1::Topic.new
|
130
|
-
name: name, labels: new_labels
|
129
|
+
update_grpc = Google::Cloud::PubSub::V1::Topic.new name: name, labels: new_labels
|
131
130
|
@grpc = service.update_topic update_grpc, :labels
|
132
131
|
@resource_name = nil
|
133
132
|
end
|
@@ -176,8 +175,7 @@ module Google
|
|
176
175
|
# topic.kms_key = key_name
|
177
176
|
#
|
178
177
|
def kms_key= new_kms_key_name
|
179
|
-
update_grpc = Google::Cloud::PubSub::V1::Topic.new
|
180
|
-
name: name, kms_key_name: new_kms_key_name
|
178
|
+
update_grpc = Google::Cloud::PubSub::V1::Topic.new name: name, kms_key_name: new_kms_key_name
|
181
179
|
@grpc = service.update_topic update_grpc, :kms_key_name
|
182
180
|
@resource_name = nil
|
183
181
|
end
|
@@ -229,9 +227,7 @@ module Google
|
|
229
227
|
#
|
230
228
|
def persistence_regions= new_persistence_regions
|
231
229
|
update_grpc = Google::Cloud::PubSub::V1::Topic.new \
|
232
|
-
name: name, message_storage_policy: {
|
233
|
-
allowed_persistence_regions: Array(new_persistence_regions)
|
234
|
-
}
|
230
|
+
name: name, message_storage_policy: { allowed_persistence_regions: Array(new_persistence_regions) }
|
235
231
|
@grpc = service.update_topic update_grpc, :message_storage_policy
|
236
232
|
@resource_name = nil
|
237
233
|
end
|
@@ -287,6 +283,8 @@ module Google
|
|
287
283
|
# values are optional. Label keys must start with a letter and each
|
288
284
|
# label in the list must have a different key. See [Creating and
|
289
285
|
# Managing Labels](https://cloud.google.com/pubsub/docs/labels).
|
286
|
+
# @param [Boolean] message_ordering Whether to enable message ordering
|
287
|
+
# on the subscription.
|
290
288
|
#
|
291
289
|
# @return [Google::Cloud::PubSub::Subscription]
|
292
290
|
#
|
@@ -309,11 +307,11 @@ module Google
|
|
309
307
|
# deadline: 120,
|
310
308
|
# endpoint: "https://example.com/push"
|
311
309
|
#
|
312
|
-
def subscribe subscription_name, deadline: nil, retain_acked: false,
|
313
|
-
|
310
|
+
def subscribe subscription_name, deadline: nil, retain_acked: false, retention: nil, endpoint: nil, labels: nil,
|
311
|
+
message_ordering: nil
|
314
312
|
ensure_service!
|
315
|
-
options = { deadline: deadline, retain_acked: retain_acked,
|
316
|
-
|
313
|
+
options = { deadline: deadline, retain_acked: retain_acked, retention: retention, endpoint: endpoint,
|
314
|
+
labels: labels, message_ordering: message_ordering }
|
317
315
|
grpc = service.create_subscription name, subscription_name, options
|
318
316
|
Subscription.from_grpc grpc, service
|
319
317
|
end
|
@@ -355,9 +353,7 @@ module Google
|
|
355
353
|
#
|
356
354
|
def subscription subscription_name, skip_lookup: nil
|
357
355
|
ensure_service!
|
358
|
-
if skip_lookup
|
359
|
-
return Subscription.from_name subscription_name, service
|
360
|
-
end
|
356
|
+
return Subscription.from_name subscription_name, service if skip_lookup
|
361
357
|
grpc = service.get_subscription subscription_name
|
362
358
|
Subscription.from_grpc grpc, service
|
363
359
|
rescue Google::Cloud::NotFoundError
|
@@ -473,17 +469,48 @@ module Google
|
|
473
469
|
end
|
474
470
|
|
475
471
|
##
|
476
|
-
# Publishes a message asynchronously to the topic
|
472
|
+
# Publishes a message asynchronously to the topic using
|
473
|
+
# {#async_publisher}.
|
477
474
|
#
|
478
475
|
# The message payload must not be empty; it must contain either a
|
479
476
|
# non-empty data field, or at least one attribute.
|
480
477
|
#
|
478
|
+
# Google Cloud Pub/Sub ordering keys provide the ability to ensure
|
479
|
+
# related messages are sent to subscribers in the order in which they
|
480
|
+
# were published. Messages can be tagged with an ordering key, a string
|
481
|
+
# that identifies related messages for which publish order should be
|
482
|
+
# respected. The service guarantees that, for a given ordering key and
|
483
|
+
# publisher, messages are sent to subscribers in the order in which they
|
484
|
+
# were published. Ordering does not require sacrificing high throughput
|
485
|
+
# or scalability, as the service automatically distributes messages for
|
486
|
+
# different ordering keys across subscribers.
|
487
|
+
#
|
488
|
+
# To use ordering keys, specify `ordering_key`. Before specifying
|
489
|
+
# `ordering_key` on a message a call to `#enable_message_ordering!` must
|
490
|
+
# be made or an error will be raised.
|
491
|
+
#
|
492
|
+
# @note At the time of this release, ordering keys are not yet publicly
|
493
|
+
# enabled and requires special project enablements.
|
494
|
+
#
|
481
495
|
# @param [String, File] data The message payload. This will be converted
|
482
496
|
# to bytes encoded as ASCII-8BIT.
|
483
497
|
# @param [Hash] attributes Optional attributes for the message.
|
498
|
+
# @param [String] ordering_key Identifies related messages for which
|
499
|
+
# publish order should be respected.
|
484
500
|
# @yield [result] the callback for when the message has been published
|
485
501
|
# @yieldparam [PublishResult] result the result of the asynchronous
|
486
502
|
# publish
|
503
|
+
# @raise [Google::Cloud::PubSub::AsyncPublisherStopped] when the
|
504
|
+
# publisher is stopped. (See {AsyncPublisher#stop} and
|
505
|
+
# {AsyncPublisher#stopped?}.)
|
506
|
+
# @raise [Google::Cloud::PubSub::OrderedMessagesDisabled] when
|
507
|
+
# publishing a message with an `ordering_key` but ordered messages are
|
508
|
+
# not enabled. (See {#message_ordering?} and
|
509
|
+
# {#enable_message_ordering!}.)
|
510
|
+
# @raise [Google::Cloud::PubSub::OrderingKeyError] when publishing a
|
511
|
+
# message with an `ordering_key` that has already failed when
|
512
|
+
# publishing. Use {#resume_publish} to allow this `ordering_key` to be
|
513
|
+
# published again.
|
487
514
|
#
|
488
515
|
# @example
|
489
516
|
# require "google/cloud/pubsub"
|
@@ -499,6 +526,7 @@ module Google
|
|
499
526
|
# end
|
500
527
|
# end
|
501
528
|
#
|
529
|
+
# # Shut down the publisher when ready to stop publishing messages.
|
502
530
|
# topic.async_publisher.stop.wait!
|
503
531
|
#
|
504
532
|
# @example A message can be published using a File object:
|
@@ -510,6 +538,7 @@ module Google
|
|
510
538
|
# file = File.open "message.txt", mode: "rb"
|
511
539
|
# topic.publish_async file
|
512
540
|
#
|
541
|
+
# # Shut down the publisher when ready to stop publishing messages.
|
513
542
|
# topic.async_publisher.stop.wait!
|
514
543
|
#
|
515
544
|
# @example Additionally, a message can be published with attributes:
|
@@ -521,13 +550,76 @@ module Google
|
|
521
550
|
# topic.publish_async "task completed",
|
522
551
|
# foo: :bar, this: :that
|
523
552
|
#
|
553
|
+
# # Shut down the publisher when ready to stop publishing messages.
|
524
554
|
# topic.async_publisher.stop.wait!
|
525
555
|
#
|
526
|
-
|
556
|
+
# @example Ordered messages are supported using ordering_key:
|
557
|
+
# require "google/cloud/pubsub"
|
558
|
+
#
|
559
|
+
# pubsub = Google::Cloud::PubSub.new
|
560
|
+
#
|
561
|
+
# topic = pubsub.topic "my-ordered-topic"
|
562
|
+
#
|
563
|
+
# # Ensure that message ordering is enabled.
|
564
|
+
# topic.enable_message_ordering!
|
565
|
+
#
|
566
|
+
# # Publish an ordered message with an ordering key.
|
567
|
+
# topic.publish_async "task completed",
|
568
|
+
# ordering_key: "task-key"
|
569
|
+
#
|
570
|
+
# # Shut down the publisher when ready to stop publishing messages.
|
571
|
+
# topic.async_publisher.stop.wait!
|
572
|
+
#
|
573
|
+
def publish_async data = nil, attributes = nil, ordering_key: nil, **extra_attrs, &callback
|
527
574
|
ensure_service!
|
528
575
|
|
529
576
|
@async_publisher ||= AsyncPublisher.new name, service, @async_opts
|
530
|
-
@async_publisher.publish data, attributes, &
|
577
|
+
@async_publisher.publish data, attributes, ordering_key: ordering_key, **extra_attrs, &callback
|
578
|
+
end
|
579
|
+
|
580
|
+
##
|
581
|
+
# Enables message ordering for messages with ordering keys on the
|
582
|
+
# {#async_publisher}. When enabled, messages published with the same
|
583
|
+
# `ordering_key` will be delivered in the order they were published.
|
584
|
+
#
|
585
|
+
# @note At the time of this release, ordering keys are not yet publicly
|
586
|
+
# enabled and requires special project enablements.
|
587
|
+
#
|
588
|
+
# See {#message_ordering?}. See {#publish_async},
|
589
|
+
# {Subscription#listen}, and {Message#ordering_key}.
|
590
|
+
#
|
591
|
+
def enable_message_ordering!
|
592
|
+
@async_publisher ||= AsyncPublisher.new name, service, @async_opts
|
593
|
+
@async_publisher.enable_message_ordering!
|
594
|
+
end
|
595
|
+
|
596
|
+
##
|
597
|
+
# Whether message ordering for messages with ordering keys has been
|
598
|
+
# enabled on the {#async_publisher}. When enabled, messages published
|
599
|
+
# with the same `ordering_key` will be delivered in the order they were
|
600
|
+
# published. When disabled, messages may be delivered in any order.
|
601
|
+
#
|
602
|
+
# See {#enable_message_ordering!}. See {#publish_async},
|
603
|
+
# {Subscription#listen}, and {Message#ordering_key}.
|
604
|
+
#
|
605
|
+
# @return [Boolean]
|
606
|
+
#
|
607
|
+
def message_ordering?
|
608
|
+
@async_publisher ||= AsyncPublisher.new name, service, @async_opts
|
609
|
+
@async_publisher.message_ordering?
|
610
|
+
end
|
611
|
+
|
612
|
+
##
|
613
|
+
# Resume publishing ordered messages for the provided ordering key.
|
614
|
+
#
|
615
|
+
# @param [String] ordering_key Identifies related messages for which
|
616
|
+
# publish order should be respected.
|
617
|
+
#
|
618
|
+
# @return [boolean] `true` when resumed, `false` otherwise.
|
619
|
+
#
|
620
|
+
def resume_publish ordering_key
|
621
|
+
@async_publisher ||= AsyncPublisher.new name, service, @async_opts
|
622
|
+
@async_publisher.resume_publish ordering_key
|
531
623
|
end
|
532
624
|
|
533
625
|
##
|