google-cloud-pubsub 2.23.0 → 3.0.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/CHANGELOG.md +18 -0
- data/OVERVIEW.md +188 -144
- data/lib/google/cloud/pubsub/admin_clients.rb +116 -0
- data/lib/google/cloud/pubsub/async_publisher.rb +9 -9
- data/lib/google/cloud/pubsub/batch_publisher.rb +4 -4
- data/lib/google/cloud/pubsub/errors.rb +3 -3
- 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 +2 -4
- data/lib/google/cloud/pubsub/{subscriber → message_listener}/sequencer.rb +1 -1
- data/lib/google/cloud/pubsub/{subscriber → message_listener}/stream.rb +10 -10
- data/lib/google/cloud/pubsub/{subscriber → message_listener}/timed_unary_buffer.rb +1 -1
- data/lib/google/cloud/pubsub/message_listener.rb +413 -0
- data/lib/google/cloud/pubsub/project.rb +98 -531
- data/lib/google/cloud/pubsub/publisher.rb +373 -0
- data/lib/google/cloud/pubsub/received_message.rb +44 -39
- data/lib/google/cloud/pubsub/service.rb +24 -386
- data/lib/google/cloud/pubsub/subscriber.rb +442 -279
- data/lib/google/cloud/pubsub/version.rb +1 -1
- data/lib/google/cloud/pubsub.rb +8 -15
- data/lib/google-cloud-pubsub.rb +5 -4
- metadata +9 -17
- 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
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright
|
1
|
+
# Copyright 2015 Google LLC
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -13,417 +13,580 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
|
16
|
-
require "google/cloud/pubsub/
|
17
|
-
require "google/cloud/
|
18
|
-
require "google/cloud/pubsub/
|
19
|
-
require "
|
16
|
+
require "google/cloud/pubsub/convert"
|
17
|
+
require "google/cloud/errors"
|
18
|
+
require "google/cloud/pubsub/received_message"
|
19
|
+
require "google/cloud/pubsub/message_listener"
|
20
|
+
require "google/cloud/pubsub/v1"
|
20
21
|
|
21
22
|
module Google
|
22
23
|
module Cloud
|
23
24
|
module PubSub
|
24
25
|
##
|
25
|
-
# Subscriber
|
26
|
-
|
26
|
+
# # Subscriber
|
27
|
+
|
28
|
+
# A {Subscriber} is the primary interface for data plane operations,
|
29
|
+
# enabling you to receive messages from a subscription, either by streaming
|
30
|
+
# with a {MessageListener} or by pulling them directly.
|
27
31
|
#
|
28
32
|
# @example
|
29
33
|
# require "google/cloud/pubsub"
|
30
34
|
#
|
31
35
|
# pubsub = Google::Cloud::PubSub.new
|
32
36
|
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
# subscriber = sub.listen do |received_message|
|
37
|
+
# subscriber = pubsub.subscriber "my-topic-sub"
|
38
|
+
# listener = subscriber.listen do |received_message|
|
36
39
|
# # process message
|
37
40
|
# received_message.acknowledge!
|
38
41
|
# end
|
39
42
|
#
|
40
|
-
# #
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
# subscriber.stop!
|
43
|
+
# # Handle exceptions from listener
|
44
|
+
# listener.on_error do |exception|
|
45
|
+
# puts "Exception: #{exception.class} #{exception.message}"
|
46
|
+
# end
|
45
47
|
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
#
|
49
|
-
#
|
50
|
-
# @attr_reader [Numeric] deadline The default number of seconds the stream
|
51
|
-
# will hold received messages before modifying the message's ack
|
52
|
-
# deadline. The minimum is 10, the maximum is 600. Default is 60.
|
53
|
-
# @attr_reader [Boolean] message_ordering Whether message ordering has
|
54
|
-
# been enabled.
|
55
|
-
# @attr_reader [Integer] streams The number of concurrent streams to open
|
56
|
-
# to pull messages from the subscription. Default is 2.
|
57
|
-
# @attr_reader [Integer] callback_threads The number of threads used to
|
58
|
-
# handle the received messages. Default is 8.
|
59
|
-
# @attr_reader [Integer] push_threads The number of threads to handle
|
60
|
-
# acknowledgement ({ReceivedMessage#ack!}) and delay messages
|
61
|
-
# ({ReceivedMessage#nack!}, {ReceivedMessage#modify_ack_deadline!}).
|
62
|
-
# Default is 4.
|
48
|
+
# # Gracefully shut down the subscriber
|
49
|
+
# at_exit do
|
50
|
+
# listener.stop!
|
51
|
+
# end
|
63
52
|
#
|
53
|
+
# # Start background threads that will call the block passed to listen.
|
54
|
+
# listener.start
|
55
|
+
# sleep
|
64
56
|
class Subscriber
|
65
|
-
include MonitorMixin
|
66
|
-
|
67
|
-
attr_reader :subscription_name
|
68
|
-
attr_reader :callback
|
69
|
-
attr_reader :deadline
|
70
|
-
attr_reader :streams
|
71
|
-
attr_reader :message_ordering
|
72
|
-
attr_reader :callback_threads
|
73
|
-
attr_reader :push_threads
|
74
|
-
|
75
57
|
##
|
76
|
-
# @private
|
77
|
-
|
58
|
+
# @private The Service object.
|
59
|
+
attr_accessor :service
|
78
60
|
|
79
61
|
##
|
80
|
-
# @private
|
81
|
-
attr_accessor :
|
62
|
+
# @private The gRPC Google::Cloud::PubSub::V1::Subscription object.
|
63
|
+
attr_accessor :grpc
|
82
64
|
|
83
65
|
##
|
84
66
|
# @private Create an empty {Subscriber} object.
|
85
|
-
def initialize
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
@
|
90
|
-
@error_callbacks = []
|
91
|
-
@subscription_name = subscription_name
|
92
|
-
@deadline = deadline || 60
|
93
|
-
@streams = streams || 2
|
94
|
-
coerce_inventory inventory
|
95
|
-
@message_ordering = message_ordering
|
96
|
-
@callback_threads = Integer(threads[:callback] || 8)
|
97
|
-
@push_threads = Integer(threads[:push] || 4)
|
98
|
-
@exactly_once_delivery_enabled = nil
|
99
|
-
|
100
|
-
@service = service
|
101
|
-
|
102
|
-
@started = @stopped = nil
|
103
|
-
|
104
|
-
stream_pool = Array.new @streams do
|
105
|
-
Thread.new { Stream.new self }
|
106
|
-
end
|
107
|
-
@stream_pool = stream_pool.map(&:value)
|
108
|
-
|
109
|
-
@buffer = TimedUnaryBuffer.new self
|
67
|
+
def initialize
|
68
|
+
@service = nil
|
69
|
+
@grpc = nil
|
70
|
+
@resource_name = nil
|
71
|
+
@exists = nil
|
110
72
|
end
|
111
73
|
|
112
74
|
##
|
113
|
-
#
|
114
|
-
# received messages.
|
75
|
+
# The underlying Subscription resource.
|
115
76
|
#
|
116
|
-
#
|
77
|
+
# Provides access to the `Google::Cloud::PubSub::V1::Subscription`
|
78
|
+
# resource managed by this subscriber.
|
117
79
|
#
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
Thread.new { stream.start }
|
127
|
-
end
|
128
|
-
end
|
129
|
-
start_pool.map(&:join)
|
130
|
-
|
131
|
-
self
|
80
|
+
# Makes an API call to retrieve the actual subscription when called
|
81
|
+
# on a reference object. See {#reference?}.
|
82
|
+
#
|
83
|
+
# @return [Google::Cloud::PubSub::V1::Subscription]
|
84
|
+
#
|
85
|
+
def subscription_resource
|
86
|
+
ensure_grpc!
|
87
|
+
@grpc
|
132
88
|
end
|
133
89
|
|
134
90
|
##
|
135
|
-
#
|
136
|
-
#
|
137
|
-
#
|
138
|
-
#
|
139
|
-
#
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
def stop
|
144
|
-
synchronize do
|
145
|
-
@started = false
|
146
|
-
@stopped = true
|
147
|
-
@stream_pool.map(&:stop)
|
148
|
-
wait_stop_buffer_thread!
|
149
|
-
self
|
150
|
-
end
|
91
|
+
# The name of the subscription.
|
92
|
+
#
|
93
|
+
# @return [String] A fully-qualified subscription name in the form
|
94
|
+
# `projects/{project_id}/subscriptions/{subscription_id}`.
|
95
|
+
#
|
96
|
+
def name
|
97
|
+
return @resource_name if reference?
|
98
|
+
@grpc.name
|
151
99
|
end
|
152
100
|
|
153
101
|
##
|
154
|
-
#
|
155
|
-
#
|
156
|
-
#
|
157
|
-
#
|
158
|
-
# Does not stop the subscriber. To stop the subscriber, first call
|
159
|
-
# {#stop} and then call {#wait!} to block until the subscriber is
|
160
|
-
# stopped.
|
102
|
+
# This value is the maximum number of seconds after a subscriber
|
103
|
+
# receives a message before the subscriber should acknowledge the
|
104
|
+
# message.
|
161
105
|
#
|
162
|
-
#
|
163
|
-
#
|
106
|
+
# Makes an API call to retrieve the deadline value when called on a
|
107
|
+
# reference object. See {#reference?}.
|
164
108
|
#
|
165
|
-
# @return [
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
@wait_stop_buffer_thread.join timeout
|
170
|
-
self
|
109
|
+
# @return [Integer]
|
110
|
+
def deadline
|
111
|
+
ensure_grpc!
|
112
|
+
@grpc.ack_deadline_seconds
|
171
113
|
end
|
172
114
|
|
173
115
|
##
|
174
|
-
#
|
175
|
-
#
|
176
|
-
#
|
116
|
+
# Whether message ordering has been enabled. When enabled, messages
|
117
|
+
# published with the same `ordering_key` will be delivered in the order
|
118
|
+
# they were published. When disabled, messages may be delivered in any
|
119
|
+
# order.
|
177
120
|
#
|
178
|
-
#
|
121
|
+
# @note At the time of this release, ordering keys are not yet publicly
|
122
|
+
# enabled and requires special project enablements.
|
179
123
|
#
|
180
|
-
#
|
181
|
-
# subscriber is fully stopped. Default will block indefinitely.
|
124
|
+
# See {Publisher#publish_async}, {#listen}, and {Message#ordering_key}.
|
182
125
|
#
|
183
|
-
#
|
126
|
+
# Makes an API call to retrieve the enable_message_ordering value when called on a
|
127
|
+
# reference object. See {#reference?}.
|
184
128
|
#
|
185
|
-
|
186
|
-
|
187
|
-
|
129
|
+
# @return [Boolean]
|
130
|
+
#
|
131
|
+
def message_ordering?
|
132
|
+
ensure_grpc!
|
133
|
+
@grpc.enable_message_ordering
|
188
134
|
end
|
189
135
|
|
190
136
|
##
|
191
|
-
#
|
137
|
+
# Determines whether the subscription exists in the Pub/Sub service.
|
192
138
|
#
|
193
|
-
#
|
139
|
+
# Makes an API call to determine whether the subscription resource
|
140
|
+
# exists when called on a reference object. See {#reference?}.
|
194
141
|
#
|
195
|
-
|
196
|
-
synchronize { @started }
|
197
|
-
end
|
198
|
-
|
199
|
-
##
|
200
|
-
# Whether the subscriber has been stopped.
|
142
|
+
# @return [Boolean]
|
201
143
|
#
|
202
|
-
# @
|
144
|
+
# @example
|
145
|
+
# require "google/cloud/pubsub"
|
146
|
+
#
|
147
|
+
# pubsub = Google::Cloud::PubSub.new
|
203
148
|
#
|
204
|
-
|
205
|
-
|
149
|
+
# subscriber = pubsub.subscriber "my-topic-sub"
|
150
|
+
# subscriber.exists? #=> true
|
151
|
+
#
|
152
|
+
def exists?
|
153
|
+
# Always true if the object is not set as reference
|
154
|
+
return true unless reference?
|
155
|
+
# If we have a value, return it
|
156
|
+
return @exists unless @exists.nil?
|
157
|
+
ensure_grpc!
|
158
|
+
@exists = true
|
159
|
+
rescue Google::Cloud::NotFoundError
|
160
|
+
@exists = false
|
206
161
|
end
|
207
162
|
|
208
163
|
##
|
209
|
-
#
|
164
|
+
# Pulls messages from the server, blocking until messages are available
|
165
|
+
# when called with the `immediate: false` option, which is recommended
|
166
|
+
# to avoid adverse impacts on the performance of pull operations.
|
210
167
|
#
|
211
|
-
#
|
212
|
-
#
|
168
|
+
# Raises an API error with status `UNAVAILABLE` if there are too many
|
169
|
+
# concurrent pull requests pending for the given subscription.
|
213
170
|
#
|
214
|
-
#
|
171
|
+
# See also {#listen} for the preferred way to process messages as they
|
172
|
+
# become available.
|
215
173
|
#
|
216
|
-
# @
|
217
|
-
#
|
174
|
+
# @param [Boolean] immediate Whether to return immediately or block until
|
175
|
+
# messages are available.
|
218
176
|
#
|
219
|
-
#
|
177
|
+
# **Warning:** The default value of this field is `true`. However, sending
|
178
|
+
# `true` is discouraged because it adversely impacts the performance of
|
179
|
+
# pull operations. We recommend that users always explicitly set this field
|
180
|
+
# to `false`.
|
181
|
+
#
|
182
|
+
# If this field set to `true`, the system will respond immediately
|
183
|
+
# even if it there are no messages available to return in the pull
|
184
|
+
# response. Otherwise, the system may wait (for a bounded amount of time)
|
185
|
+
# until at least one message is available, rather than returning no messages.
|
186
|
+
#
|
187
|
+
# See also {#listen} for the preferred way to process messages as they
|
188
|
+
# become available.
|
189
|
+
# @param [Integer] max The maximum number of messages to return for this
|
190
|
+
# request. The Pub/Sub system may return fewer than the number
|
191
|
+
# specified. The default value is `100`, the maximum value is `1000`.
|
192
|
+
#
|
193
|
+
# @return [Array<Google::Cloud::PubSub::ReceivedMessage>]
|
194
|
+
#
|
195
|
+
# @example The `immediate: false` option is now recommended to avoid adverse impacts on pull operations:
|
220
196
|
# require "google/cloud/pubsub"
|
221
197
|
#
|
222
198
|
# pubsub = Google::Cloud::PubSub.new
|
223
199
|
#
|
224
|
-
#
|
225
|
-
#
|
226
|
-
#
|
227
|
-
# # process message
|
200
|
+
# subscriber = pubsub.subscriber "my-topic-sub"
|
201
|
+
# received_messages = subscriber.pull immediate: false
|
202
|
+
# received_messages.each do |received_message|
|
228
203
|
# received_message.acknowledge!
|
229
204
|
# end
|
230
205
|
#
|
231
|
-
#
|
232
|
-
#
|
233
|
-
# # log error
|
234
|
-
# puts error
|
235
|
-
# end
|
206
|
+
# @example A maximum number of messages returned can also be specified:
|
207
|
+
# require "google/cloud/pubsub"
|
236
208
|
#
|
237
|
-
#
|
238
|
-
# subscriber.start
|
209
|
+
# pubsub = Google::Cloud::PubSub.new
|
239
210
|
#
|
240
|
-
#
|
241
|
-
# subscriber.
|
211
|
+
# subscriber = pubsub.subscriber "my-topic-sub"
|
212
|
+
# received_messages = subscriber.pull immediate: false, max: 10
|
213
|
+
# received_messages.each do |received_message|
|
214
|
+
# received_message.acknowledge!
|
215
|
+
# end
|
242
216
|
#
|
243
|
-
def
|
244
|
-
|
245
|
-
|
217
|
+
def pull immediate: true, max: 100
|
218
|
+
ensure_service!
|
219
|
+
options = { immediate: immediate, max: max }
|
220
|
+
list_grpc = service.pull name, options
|
221
|
+
Array(list_grpc.received_messages).map do |msg_grpc|
|
222
|
+
ReceivedMessage.from_grpc msg_grpc, self
|
246
223
|
end
|
224
|
+
rescue Google::Cloud::DeadlineExceededError
|
225
|
+
[]
|
247
226
|
end
|
248
227
|
|
249
228
|
##
|
250
|
-
#
|
251
|
-
#
|
229
|
+
# Pulls from the server while waiting for messages to become available.
|
230
|
+
# This is the same as:
|
231
|
+
#
|
232
|
+
# subscriber.pull immediate: false
|
233
|
+
#
|
234
|
+
# See also {#listen} for the preferred way to process messages as they
|
235
|
+
# become available.
|
236
|
+
#
|
237
|
+
# @param [Integer] max The maximum number of messages to return for this
|
238
|
+
# request. The Pub/Sub system may return fewer than the number
|
239
|
+
# specified. The default value is `100`, the maximum value is `1000`.
|
240
|
+
#
|
241
|
+
# @return [Array<Google::Cloud::PubSub::ReceivedMessage>]
|
242
|
+
#
|
243
|
+
# @example
|
244
|
+
# require "google/cloud/pubsub"
|
252
245
|
#
|
253
|
-
#
|
254
|
-
# recover from the error and resume listening.
|
246
|
+
# pubsub = Google::Cloud::PubSub.new
|
255
247
|
#
|
256
|
-
#
|
248
|
+
# subscriber = pubsub.subscriber "my-topic-sub"
|
249
|
+
# received_messages = subscriber.wait_for_messages
|
250
|
+
# received_messages.each do |received_message|
|
251
|
+
# received_message.acknowledge!
|
252
|
+
# end
|
253
|
+
#
|
254
|
+
def wait_for_messages max: 100
|
255
|
+
pull immediate: false, max: max
|
256
|
+
end
|
257
|
+
|
258
|
+
##
|
259
|
+
# Create a {MessageListener} object that receives and processes messages
|
260
|
+
# using the code provided in the callback. Messages passed to the
|
261
|
+
# callback should acknowledge ({ReceivedMessage#acknowledge!}) or reject
|
262
|
+
# ({ReceivedMessage#reject!}) the message. If no action is taken, the
|
263
|
+
# message will be removed from the subscriber and made available for
|
264
|
+
# redelivery after the callback is completed.
|
265
|
+
#
|
266
|
+
# Google Cloud Pub/Sub ordering keys provide the ability to ensure
|
267
|
+
# related messages are sent to subscribers in the order in which they
|
268
|
+
# were published. Messages can be tagged with an ordering key, a string
|
269
|
+
# that identifies related messages for which publish order should be
|
270
|
+
# respected. The service guarantees that, for a given ordering key and
|
271
|
+
# publisher, messages are sent to subscribers in the order in which they
|
272
|
+
# were published. Ordering does not require sacrificing high throughput
|
273
|
+
# or scalability, as the service automatically distributes messages for
|
274
|
+
# different ordering keys across subscribers.
|
275
|
+
#
|
276
|
+
# To use ordering keys, the subscription must be created with message
|
277
|
+
# ordering enabled before calling {#listen}. When enabled, the subscriber
|
278
|
+
# will deliver messages with the same `ordering_key` in the order they were
|
279
|
+
# published.
|
280
|
+
#
|
281
|
+
# @note At the time of this release, ordering keys are not yet publicly
|
282
|
+
# enabled and requires special project enablements.
|
283
|
+
#
|
284
|
+
# @param [Numeric] deadline The default number of seconds the stream
|
285
|
+
# will hold received messages before modifying the message's ack
|
286
|
+
# deadline. The minimum is 10, the maximum is 600. Default is
|
287
|
+
# {#deadline}. Optional.
|
288
|
+
#
|
289
|
+
# When using a reference object an API call will be made to retrieve
|
290
|
+
# the default deadline value for the subscription when this argument
|
291
|
+
# is not provided. See {#reference?}.
|
292
|
+
# @param [Boolean] message_ordering Whether message ordering has been
|
293
|
+
# enabled. The value provided must match the value set on the Pub/Sub
|
294
|
+
# service. See {#message_ordering?}. Optional.
|
295
|
+
#
|
296
|
+
# When using a reference object an API call will be made to retrieve
|
297
|
+
# the default message_ordering value for the subscription when this
|
298
|
+
# argument is not provided. See {#reference?}.
|
299
|
+
# @param [Integer] streams The number of concurrent streams to open to
|
300
|
+
# pull messages from the subscription. Default is 1. Optional.
|
301
|
+
# @param [Hash, Integer] inventory The settings to control how received messages are to be handled by the
|
302
|
+
# subscriber. When provided as an Integer instead of a Hash only `max_outstanding_messages` will be set.
|
303
|
+
# Optional.
|
304
|
+
#
|
305
|
+
# Hash keys and values may include the following:
|
306
|
+
#
|
307
|
+
# * `:max_outstanding_messages` [Integer] The number of received messages to be collected by subscriber.
|
308
|
+
# Default is 1,000. (Note: replaces `:limit`, which is deprecated.)
|
309
|
+
# * `:max_outstanding_bytes` [Integer] The total byte size of received messages to be collected by
|
310
|
+
# subscriber. Default is 100,000,000 (100MB). (Note: replaces `:bytesize`, which is deprecated.)
|
311
|
+
# * `:max_total_lease_duration` [Integer] The number of seconds that received messages can be held awaiting
|
312
|
+
# processing. Default is 3,600 (1 hour). (Note: replaces `:extension`, which is deprecated.)
|
313
|
+
# * `:max_duration_per_lease_extension` [Integer] The maximum amount of time in seconds for a single lease
|
314
|
+
# extension attempt. Bounds the delay before a message redelivery if the subscriber fails to extend the
|
315
|
+
# deadline. Default is 0 (disabled).
|
316
|
+
# @param [Hash] threads The number of threads to create to handle
|
317
|
+
# concurrent calls by each stream opened by the subscriber. Optional.
|
318
|
+
#
|
319
|
+
# Hash keys and values may include the following:
|
320
|
+
#
|
321
|
+
# * `:callback` (Integer) The number of threads used to handle the
|
322
|
+
# received messages. Default is 8.
|
323
|
+
# * `:push` (Integer) The number of threads to handle
|
324
|
+
# acknowledgement ({ReceivedMessage#ack!}) and modify ack deadline
|
325
|
+
# messages ({ReceivedMessage#nack!},
|
326
|
+
# {ReceivedMessage#modify_ack_deadline!}). Default is 4.
|
327
|
+
#
|
328
|
+
# @yield [received_message] a block for processing new messages
|
329
|
+
# @yieldparam [ReceivedMessage] received_message the newly received
|
330
|
+
# message
|
331
|
+
#
|
332
|
+
# @return [MessageListener]
|
257
333
|
#
|
258
334
|
# @example
|
259
335
|
# require "google/cloud/pubsub"
|
260
336
|
#
|
261
337
|
# pubsub = Google::Cloud::PubSub.new
|
262
338
|
#
|
263
|
-
#
|
339
|
+
# subscriber = pubsub.subscriber "my-topic-sub"
|
264
340
|
#
|
265
|
-
#
|
341
|
+
# listener = subscriber.listen do |received_message|
|
266
342
|
# # process message
|
343
|
+
# puts "Data: #{received_message.message.data}, published at #{received_message.message.published_at}"
|
267
344
|
# received_message.acknowledge!
|
268
345
|
# end
|
269
346
|
#
|
270
|
-
# # Start
|
271
|
-
#
|
347
|
+
# # Start background threads that will call block passed to listen.
|
348
|
+
# listener.start
|
349
|
+
#
|
350
|
+
# # Shut down the subscriber when ready to stop receiving messages.
|
351
|
+
# listener.stop!
|
352
|
+
#
|
353
|
+
# @example Configuring to increase concurrent callbacks:
|
354
|
+
# require "google/cloud/pubsub"
|
355
|
+
#
|
356
|
+
# pubsub = Google::Cloud::PubSub.new
|
272
357
|
#
|
273
|
-
#
|
274
|
-
#
|
358
|
+
# subscriber = pubsub.subscriber "my-topic-sub"
|
359
|
+
#
|
360
|
+
# listener = subscriber.listen threads: { callback: 16 } do |rec_message|
|
361
|
+
# # store the message somewhere before acknowledging
|
362
|
+
# store_in_backend rec_message.data # takes a few seconds
|
363
|
+
# rec_message.acknowledge!
|
364
|
+
# end
|
365
|
+
#
|
366
|
+
# # Start background threads that will call block passed to listen.
|
367
|
+
# listener.start
|
275
368
|
#
|
276
369
|
# # Shut down the subscriber when ready to stop receiving messages.
|
277
|
-
#
|
370
|
+
# listener.stop!
|
278
371
|
#
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
#
|
372
|
+
# @example Ordered messages are supported using ordering_key:
|
373
|
+
# require "google/cloud/pubsub"
|
374
|
+
#
|
375
|
+
# pubsub = Google::Cloud::PubSub.new
|
376
|
+
#
|
377
|
+
# subscriber = pubsub.subscriber "my-ordered-topic-sub"
|
378
|
+
# subscriber.message_ordering? #=> true
|
379
|
+
#
|
380
|
+
# listener = subscriber.listen do |received_message|
|
381
|
+
# # messsages with the same ordering_key are received
|
382
|
+
# # in the order in which they were published.
|
383
|
+
# received_message.acknowledge!
|
384
|
+
# end
|
385
|
+
#
|
386
|
+
# # Start background threads that will call block passed to listen.
|
387
|
+
# listener.start
|
388
|
+
#
|
389
|
+
# # Shut down the subscriber when ready to stop receiving messages.
|
390
|
+
# listener.stop!
|
391
|
+
#
|
392
|
+
# @example Set the maximum amount of time before redelivery if the subscriber fails to extend the deadline:
|
393
|
+
# require "google/cloud/pubsub"
|
394
|
+
#
|
395
|
+
# pubsub = Google::Cloud::PubSub.new
|
396
|
+
#
|
397
|
+
# subscriber = pubsub.subscriber "my-topic-sub"
|
398
|
+
#
|
399
|
+
# listener = subscriber.listen inventory: { max_duration_per_lease_extension: 20 } do |received_message|
|
400
|
+
# # Process message very slowly with possibility of failure.
|
401
|
+
# process rec_message.data # takes minutes
|
402
|
+
# rec_message.acknowledge!
|
403
|
+
# end
|
404
|
+
#
|
405
|
+
# # Start background threads that will call block passed to listen.
|
406
|
+
# listener.start
|
285
407
|
#
|
286
|
-
#
|
408
|
+
# # Shut down the subscriber when ready to stop receiving messages.
|
409
|
+
# listener.stop!
|
287
410
|
#
|
288
|
-
def
|
289
|
-
|
411
|
+
def listen deadline: nil, message_ordering: nil, streams: nil, inventory: nil, threads: {}, &block
|
412
|
+
ensure_service!
|
413
|
+
deadline ||= self.deadline
|
414
|
+
message_ordering = message_ordering? if message_ordering.nil?
|
415
|
+
|
416
|
+
MessageListener.new name, block, deadline: deadline, streams: streams, inventory: inventory,
|
417
|
+
message_ordering: message_ordering, threads: threads, service: service
|
290
418
|
end
|
291
|
-
# @deprecated Use {#max_outstanding_messages}.
|
292
|
-
alias inventory_limit max_outstanding_messages
|
293
|
-
# @deprecated Use {#max_outstanding_messages}.
|
294
|
-
alias inventory max_outstanding_messages
|
295
419
|
|
296
420
|
##
|
297
|
-
#
|
421
|
+
# Acknowledges receipt of a message. After an ack,
|
422
|
+
# the Pub/Sub system can remove the message from the subscription.
|
423
|
+
# Acknowledging a message whose ack deadline has expired may succeed,
|
424
|
+
# although the message may have been sent again.
|
425
|
+
# Acknowledging a message more than once will not result in an error.
|
426
|
+
# This is only used for messages received via pull.
|
427
|
+
#
|
428
|
+
# See also {ReceivedMessage#acknowledge!}.
|
429
|
+
#
|
430
|
+
# @param [ReceivedMessage, String] messages One or more
|
431
|
+
# {ReceivedMessage} objects or ack_id values.
|
432
|
+
#
|
433
|
+
# @example
|
434
|
+
# require "google/cloud/pubsub"
|
298
435
|
#
|
299
|
-
#
|
436
|
+
# pubsub = Google::Cloud::PubSub.new
|
437
|
+
#
|
438
|
+
# subscriber = pubsub.subscriber "my-topic-sub"
|
439
|
+
# received_messages = sub.pull immediate: false
|
440
|
+
# subscriber.acknowledge received_messages
|
300
441
|
#
|
301
|
-
def
|
302
|
-
|
442
|
+
def acknowledge *messages
|
443
|
+
ack_ids = coerce_ack_ids messages
|
444
|
+
return true if ack_ids.empty?
|
445
|
+
ensure_service!
|
446
|
+
service.acknowledge name, *ack_ids
|
447
|
+
true
|
303
448
|
end
|
304
|
-
|
305
|
-
alias inventory_bytesize max_outstanding_bytes
|
449
|
+
alias ack acknowledge
|
306
450
|
|
307
451
|
##
|
308
|
-
#
|
309
|
-
#
|
452
|
+
# Modifies the acknowledge deadline for messages.
|
453
|
+
#
|
454
|
+
# This indicates that more time is needed to process the messages, or to
|
455
|
+
# make the messages available for redelivery if the processing was
|
456
|
+
# interrupted.
|
457
|
+
#
|
458
|
+
# See also {ReceivedMessage#modify_ack_deadline!}.
|
459
|
+
#
|
460
|
+
# @param [Integer] new_deadline The new ack deadline in seconds from the
|
461
|
+
# time this request is sent to the Pub/Sub system. Must be >= 0. For
|
462
|
+
# example, if the value is `10`, the new ack deadline will expire 10
|
463
|
+
# seconds after the call is made. Specifying `0` may immediately make
|
464
|
+
# the message available for another pull request.
|
465
|
+
# @param [ReceivedMessage, String] messages One or more
|
466
|
+
# {ReceivedMessage} objects or ack_id values.
|
310
467
|
#
|
311
|
-
# @
|
312
|
-
#
|
468
|
+
# @example
|
469
|
+
# require "google/cloud/pubsub"
|
470
|
+
#
|
471
|
+
# pubsub = Google::Cloud::PubSub.new
|
313
472
|
#
|
314
|
-
|
315
|
-
|
473
|
+
# subscriber = pubsub.subscriber "my-topic-sub"
|
474
|
+
# received_messages = subscriber.pull immediate: false
|
475
|
+
# subscriber.modify_ack_deadline 120, received_messages
|
476
|
+
#
|
477
|
+
def modify_ack_deadline new_deadline, *messages
|
478
|
+
ack_ids = coerce_ack_ids messages
|
479
|
+
ensure_service!
|
480
|
+
service.modify_ack_deadline name, ack_ids, new_deadline
|
481
|
+
true
|
316
482
|
end
|
317
483
|
|
318
484
|
##
|
319
|
-
#
|
485
|
+
# Determines whether the subscription object was created without
|
486
|
+
# retrieving the resource representation from the Pub/Sub service.
|
320
487
|
#
|
321
|
-
# @return [
|
488
|
+
# @return [Boolean] `true` when the subscription was created without a
|
489
|
+
# resource representation, `false` otherwise.
|
322
490
|
#
|
323
|
-
|
324
|
-
|
491
|
+
# @example
|
492
|
+
# require "google/cloud/pubsub"
|
493
|
+
#
|
494
|
+
# pubsub = Google::Cloud::PubSub.new
|
495
|
+
#
|
496
|
+
# subscriber = pubsub.subscriber "my-topic-sub", skip_lookup: true
|
497
|
+
#
|
498
|
+
# subscriber.reference? #=> true
|
499
|
+
#
|
500
|
+
def reference?
|
501
|
+
@grpc.nil?
|
325
502
|
end
|
326
|
-
# @deprecated Use {#max_total_lease_duration}.
|
327
|
-
alias inventory_extension max_total_lease_duration
|
328
503
|
|
329
504
|
##
|
330
|
-
#
|
331
|
-
#
|
505
|
+
# Determines whether the subscription object was created with a resource
|
506
|
+
# representation from the Pub/Sub service.
|
507
|
+
#
|
508
|
+
# @return [Boolean] `true` when the subscription was created with a
|
509
|
+
# resource representation, `false` otherwise.
|
332
510
|
#
|
333
|
-
# @
|
511
|
+
# @example
|
512
|
+
# require "google/cloud/pubsub"
|
513
|
+
#
|
514
|
+
# pubsub = Google::Cloud::PubSub.new
|
515
|
+
#
|
516
|
+
# subscriber = pubsub.subscriber "my-topic-sub"
|
334
517
|
#
|
335
|
-
|
336
|
-
|
518
|
+
# subscriber.resource? #=> true
|
519
|
+
#
|
520
|
+
def resource?
|
521
|
+
!@grpc.nil?
|
337
522
|
end
|
338
523
|
|
339
524
|
##
|
340
|
-
#
|
341
|
-
#
|
525
|
+
# Reloads the subscription with current data from the Pub/Sub service.
|
526
|
+
#
|
527
|
+
# @return [Google::Cloud::PubSub::Subscription] Returns the reloaded
|
528
|
+
# subscription
|
342
529
|
#
|
343
|
-
# @
|
530
|
+
# @example
|
531
|
+
# require "google/cloud/pubsub"
|
344
532
|
#
|
345
|
-
|
346
|
-
|
533
|
+
# pubsub = Google::Cloud::PubSub.new
|
534
|
+
#
|
535
|
+
# sub = Google::Cloud::PubSub::Subscriber.from_name "my-topic-sub", pubsub.service
|
536
|
+
#
|
537
|
+
# sub.reload!
|
538
|
+
#
|
539
|
+
def reload!
|
540
|
+
ensure_service!
|
541
|
+
subscription_path = service.subscription_path name
|
542
|
+
@grpc = service.subscription_admin.get_subscription subscription: subscription_path
|
543
|
+
@resource_name = nil
|
544
|
+
self
|
347
545
|
end
|
348
546
|
|
349
547
|
##
|
350
548
|
# @private
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
min_duration_per_lease_extension: @inventory[:min_duration_per_lease_extension],
|
358
|
-
use_legacy_flow_control: @inventory[:use_legacy_flow_control]
|
359
|
-
}
|
360
|
-
end
|
361
|
-
|
362
|
-
# @private returns error object from the stream thread.
|
363
|
-
def error! error
|
364
|
-
error_callbacks = synchronize do
|
365
|
-
@last_error = error
|
366
|
-
@error_callbacks
|
549
|
+
# New Subscriber from a Google::Cloud::PubSub::V1::Subscription
|
550
|
+
# object.
|
551
|
+
def self.from_grpc grpc, service
|
552
|
+
new.tap do |f|
|
553
|
+
f.grpc = grpc
|
554
|
+
f.service = service
|
367
555
|
end
|
368
|
-
error_callbacks = default_error_callbacks if error_callbacks.empty?
|
369
|
-
error_callbacks.each { |error_callback| error_callback.call error }
|
370
556
|
end
|
371
557
|
|
372
558
|
##
|
373
|
-
# @private
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
def inspect
|
381
|
-
"#<#{self.class.name} #{self}>"
|
559
|
+
# @private New reference {Subscriber} object without making an HTTP
|
560
|
+
# request.
|
561
|
+
def self.from_name name, service, options = {}
|
562
|
+
name = service.subscription_path name, options
|
563
|
+
from_grpc(nil, service).tap do |s|
|
564
|
+
s.instance_variable_set :@resource_name, name
|
565
|
+
end
|
382
566
|
end
|
383
567
|
|
384
568
|
protected
|
385
569
|
|
386
570
|
##
|
387
|
-
#
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
@stream_pool.map(&:wait!)
|
392
|
-
# Shutdown the buffer TimerTask (and flush the buffer) after the streams are all stopped.
|
393
|
-
@buffer.stop
|
394
|
-
end
|
395
|
-
end
|
571
|
+
# @private Raise an error unless an active connection to the service is
|
572
|
+
# available.
|
573
|
+
def ensure_service!
|
574
|
+
raise "Must have active connection to service" unless service
|
396
575
|
end
|
397
576
|
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
@inventory[:max_outstanding_messages] ||= @inventory.delete :limit
|
404
|
-
@inventory[:max_outstanding_bytes] ||= @inventory.delete :bytesize
|
405
|
-
@inventory[:max_total_lease_duration] ||= @inventory.delete :extension
|
406
|
-
else
|
407
|
-
@inventory = { max_outstanding_messages: @inventory }
|
408
|
-
end
|
409
|
-
@inventory[:max_outstanding_messages] = Integer(@inventory[:max_outstanding_messages] || 1000)
|
410
|
-
@inventory[:max_outstanding_bytes] = Integer(@inventory[:max_outstanding_bytes] || 100_000_000)
|
411
|
-
@inventory[:max_total_lease_duration] = Integer(@inventory[:max_total_lease_duration] || 3600)
|
412
|
-
@inventory[:max_duration_per_lease_extension] = Integer(@inventory[:max_duration_per_lease_extension] || 0)
|
413
|
-
@inventory[:min_duration_per_lease_extension] = Integer(@inventory[:min_duration_per_lease_extension] || 0)
|
414
|
-
@inventory[:use_legacy_flow_control] = @inventory[:use_legacy_flow_control] || false
|
577
|
+
##
|
578
|
+
# Ensures a Google::Cloud::PubSub::V1::Subscription object exists.
|
579
|
+
def ensure_grpc!
|
580
|
+
ensure_service!
|
581
|
+
reload! if reference?
|
415
582
|
end
|
416
583
|
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
[error_callback]
|
424
|
-
else
|
425
|
-
[]
|
426
|
-
end
|
584
|
+
##
|
585
|
+
# Makes sure the values are the `ack_id`. If given several
|
586
|
+
# {ReceivedMessage} objects extract the `ack_id` values.
|
587
|
+
def coerce_ack_ids messages
|
588
|
+
Array(messages).flatten.map do |msg|
|
589
|
+
msg.respond_to?(:ack_id) ? msg.ack_id : msg.to_s
|
427
590
|
end
|
428
591
|
end
|
429
592
|
end
|