google-cloud-pubsub 0.24.0 → 0.25.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
  SHA1:
3
- metadata.gz: b3e195a29890f73bda2b6a0b6caa90a9c8570454
4
- data.tar.gz: 6663923bc7039afc67d791d02215109ca70ac083
3
+ metadata.gz: 010d13829a25c127763e29f5c44826325d2ac57b
4
+ data.tar.gz: 4dd99f0b95e7c054b05794df5a502550d5481bf8
5
5
  SHA512:
6
- metadata.gz: 8851ed8c44d1f85bef860c026bfc014726dc2bcf1ca90b6e70fbde6a9c4484e6585bcfe9880821fc783e1ce85b807537c73b3f2c62c97921d4b7717a78459462
7
- data.tar.gz: 148697983bbdeb834e4bd261502dd518d0edb104004768f47634fbe68fc2cf0f85f32022cdb4303875c8d8ced2496158cb8a63360f07926fcf6f33800997ee69
6
+ metadata.gz: da3fe9646eae5487c32352fdc938883d73af6535ab4b1869033cbf1a8ddc74d13362967228bee132dada097d37e46b5f1f7de6114647ed15024b1187a7ece94a
7
+ data.tar.gz: b7f054ffd0e941ba6128c5f189ea69357ddf06e3dff36a0fd190278ebdfb2f02111dca12011cc07b10bc15d5d8788e40789ab45ddec2085be622bd03d9994b69
data/README.md CHANGED
@@ -24,7 +24,7 @@ Instructions and configuration options are covered in the [Authentication Guide]
24
24
  require "google/cloud/pubsub"
25
25
 
26
26
  pubsub = Google::Cloud::Pubsub.new(
27
- project: "my-todo-project",
27
+ project: "my-project",
28
28
  keyfile: "/path/to/keyfile.json"
29
29
  )
30
30
 
@@ -131,7 +131,7 @@ module Google
131
131
  # pubsub = Google::Cloud::Pubsub.new
132
132
  #
133
133
  # topic = pubsub.topic "my-topic"
134
- # msg = topic.publish "new-message"
134
+ # msg = topic.publish "task completed"
135
135
  # ```
136
136
  #
137
137
  # Messages can also be published with attributes:
@@ -142,7 +142,7 @@ module Google
142
142
  # pubsub = Google::Cloud::Pubsub.new
143
143
  #
144
144
  # topic = pubsub.topic "my-topic"
145
- # msg = topic.publish "new-message",
145
+ # msg = topic.publish "task completed",
146
146
  # foo: :bar,
147
147
  # this: :that
148
148
  # ```
@@ -156,9 +156,9 @@ module Google
156
156
  #
157
157
  # topic = pubsub.topic "my-topic"
158
158
  # msgs = topic.publish do |batch|
159
- # batch.publish "new-message-1", foo: :bar
160
- # batch.publish "new-message-2", foo: :baz
161
- # batch.publish "new-message-3", foo: :bif
159
+ # batch.publish "task 1 completed", foo: :bar
160
+ # batch.publish "task 2 completed", foo: :baz
161
+ # batch.publish "task 3 completed", foo: :bif
162
162
  # end
163
163
  # ```
164
164
  #
@@ -281,6 +281,34 @@ module Google
281
281
  # sub.delay 120, received_messages
282
282
  # ```
283
283
  #
284
+ # ## Creating a snapshot and using seek
285
+ #
286
+ # You can create a snapshot to retain the existing backlog on a
287
+ # subscription. The snapshot will hold the messages in the subscription's
288
+ # backlog that are unacknowledged upon the successful completion of the
289
+ # `create_snapshot` operation.
290
+ #
291
+ # Later, you can use `seek` to reset the subscription's backlog to the
292
+ # snapshot.
293
+ #
294
+ # (See {Google::Cloud::Pubsub::Subscription#create_snapshot} and
295
+ # {Google::Cloud::Pubsub::Subscription#seek})
296
+ #
297
+ # ```ruby
298
+ # require "google/cloud/pubsub"
299
+ #
300
+ # pubsub = Google::Cloud::Pubsub.new
301
+ #
302
+ # sub = pubsub.subscription "my-topic-sub"
303
+ #
304
+ # snapshot = sub.create_snapshot
305
+ #
306
+ # messages = sub.pull
307
+ # sub.acknowledge messages
308
+ #
309
+ # sub.seek snapshot
310
+ # ```
311
+ #
284
312
  # ## Listening for Messages
285
313
  #
286
314
  # Long running workers are easy to create with `listen`, which runs an
@@ -35,13 +35,13 @@ module Google
35
35
  #
36
36
  # # Publish a message
37
37
  # topic = pubsub.topic "my-topic"
38
- # message = topic.publish "new-message"
39
- # puts message.data #=> "new-message"
38
+ # message = topic.publish "task completed"
39
+ # message.data #=> "task completed"
40
40
  #
41
41
  # # Pull a message
42
42
  # sub = pubsub.subscription "my-topic-sub"
43
43
  # received_message = sub.pull.first
44
- # puts received_message.message.data #=> "new-message"
44
+ # received_message.message.data #=> "task completed"
45
45
  #
46
46
  class Message
47
47
  ##
@@ -61,13 +61,11 @@ module Google
61
61
  # pubsub = Google::Cloud::Pubsub.new
62
62
  # topic = pubsub.topic "my-topic"
63
63
  #
64
- # policy = topic.policy # API call
65
- #
66
- # policy.remove "roles/owner", "user:owner@example.com" # Local call
67
- # policy.add "roles/owner", "user:newowner@example.com" # Local call
68
- # policy.roles["roles/viewer"] = ["allUsers"] # Local call
69
- #
70
- # topic.policy = policy # API call
64
+ # topic.policy do |p|
65
+ # p.remove "roles/owner", "user:owner@example.com"
66
+ # p.add "roles/owner", "user:newowner@example.com"
67
+ # p.roles["roles/viewer"] = ["allUsers"]
68
+ # end
71
69
  #
72
70
  class Policy
73
71
  attr_reader :etag, :roles
@@ -98,11 +96,9 @@ module Google
98
96
  # pubsub = Google::Cloud::Pubsub.new
99
97
  # topic = pubsub.topic "my-topic"
100
98
  #
101
- # policy = topic.policy # API call
102
- #
103
- # policy.add "roles/owner", "user:newowner@example.com" # Local call
104
- #
105
- # topic.policy = policy # API call
99
+ # topic.policy do |p|
100
+ # p.add "roles/owner", "user:newowner@example.com"
101
+ # end
106
102
  #
107
103
  def add role_name, member
108
104
  role(role_name) << member
@@ -127,11 +123,9 @@ module Google
127
123
  # pubsub = Google::Cloud::Pubsub.new
128
124
  # topic = pubsub.topic "my-topic"
129
125
  #
130
- # policy = topic.policy # API call
131
- #
132
- # policy.remove "roles/owner", "user:owner@example.com" # Local call
133
- #
134
- # topic.policy = policy # API call
126
+ # topic.policy do |p|
127
+ # p.remove "roles/owner", "user:owner@example.com"
128
+ # end
135
129
  #
136
130
  def remove role_name, member
137
131
  role(role_name).delete member
@@ -154,28 +148,14 @@ module Google
154
148
  # pubsub = Google::Cloud::Pubsub.new
155
149
  # topic = pubsub.topic "my-topic"
156
150
  #
157
- # policy = topic.policy
158
- #
159
- # policy.role("roles/viewer") << "user:viewer@example.com"
151
+ # topic.policy do |p|
152
+ # p.role("roles/viewer") << "user:viewer@example.com"
153
+ # end
160
154
  #
161
155
  def role role_name
162
156
  roles[role_name] ||= []
163
157
  end
164
158
 
165
- ##
166
- # Returns a deep copy of the policy.
167
- #
168
- # @return [Policy]
169
- #
170
- def deep_dup
171
- dup.tap do |p|
172
- roles_dup = p.roles.each_with_object({}) do |(k, v), memo|
173
- memo[k] = v.dup rescue value
174
- end
175
- p.instance_variable_set "@roles", roles_dup
176
- end
177
- end
178
-
179
159
  ##
180
160
  # @private Convert the Policy to a Google::Iam::V1::Policy object.
181
161
  def to_grpc
@@ -18,6 +18,7 @@ require "google/cloud/env"
18
18
  require "google/cloud/pubsub/service"
19
19
  require "google/cloud/pubsub/credentials"
20
20
  require "google/cloud/pubsub/topic"
21
+ require "google/cloud/pubsub/snapshot"
21
22
 
22
23
  module Google
23
24
  module Cloud
@@ -60,11 +61,11 @@ module Google
60
61
  # require "google/cloud/pubsub"
61
62
  #
62
63
  # pubsub = Google::Cloud::Pubsub.new(
63
- # project: "my-todo-project",
64
+ # project: "my-project",
64
65
  # keyfile: "/path/to/keyfile.json"
65
66
  # )
66
67
  #
67
- # pubsub.project #=> "my-todo-project"
68
+ # pubsub.project #=> "my-project"
68
69
  #
69
70
  def project
70
71
  service.project
@@ -112,7 +113,7 @@ module Google
112
113
  # require "google/cloud/pubsub"
113
114
  #
114
115
  # pubsub = Google::Cloud::Pubsub.new
115
- # topic = pubsub.topic "non-existing-topic" #=> nil
116
+ # topic = pubsub.topic "non-existing-topic" # nil
116
117
  #
117
118
  # @example With the `autocreate` option set to `true`.
118
119
  # require "google/cloud/pubsub"
@@ -231,7 +232,7 @@ module Google
231
232
  #
232
233
  # pubsub = Google::Cloud::Pubsub.new
233
234
  #
234
- # msg = pubsub.publish "my-topic", "new-message"
235
+ # msg = pubsub.publish "my-topic", "task completed"
235
236
  #
236
237
  # @example A message can be published using a File object:
237
238
  # require "google/cloud/pubsub"
@@ -245,7 +246,7 @@ module Google
245
246
  #
246
247
  # pubsub = Google::Cloud::Pubsub.new
247
248
  #
248
- # msg = pubsub.publish "my-topic", "new-message", foo: :bar,
249
+ # msg = pubsub.publish "my-topic", "task completed", foo: :bar,
249
250
  # this: :that
250
251
  #
251
252
  # @example Multiple messages can be sent at the same time using a block:
@@ -254,9 +255,9 @@ module Google
254
255
  # pubsub = Google::Cloud::Pubsub.new
255
256
  #
256
257
  # msgs = pubsub.publish "my-topic" do |p|
257
- # p.publish "new-message-1", foo: :bar
258
- # p.publish "new-message-2", foo: :baz
259
- # p.publish "new-message-3", foo: :bif
258
+ # p.publish "task 1 completed", foo: :bar
259
+ # p.publish "task 2 completed", foo: :baz
260
+ # p.publish "task 3 completed", foo: :bif
260
261
  # end
261
262
  #
262
263
  # @example With `autocreate`:
@@ -264,7 +265,7 @@ module Google
264
265
  #
265
266
  # pubsub = Google::Cloud::Pubsub.new
266
267
  #
267
- # msg = pubsub.publish "new-topic", "new-message", autocreate: true
268
+ # msg = pubsub.publish "new-topic", "task completed", autocreate: true
268
269
  #
269
270
  def publish topic_name, data = nil, attributes = {}
270
271
  # Fix parameters
@@ -295,6 +296,17 @@ module Google
295
296
  # @param [Integer] deadline The maximum number of seconds after a
296
297
  # subscriber receives a message before the subscriber should
297
298
  # acknowledge the message.
299
+ # @param [Boolean] retain_acked Indicates whether to retain acknowledged
300
+ # messages. If `true`, then messages are not expunged from the
301
+ # subscription's backlog, even if they are acknowledged, until they
302
+ # fall out of the `retention_duration` window. Default is `false`.
303
+ # @param [Numeric] retention How long to retain unacknowledged messages
304
+ # in the subscription's backlog, from the moment a message is
305
+ # published. If `retain_acked` is `true`, then this also configures
306
+ # the retention of acknowledged messages, and thus configures how far
307
+ # back in time a {#seek} can be done. Cannot be more than 604,800
308
+ # seconds (7 days) or less than 600 seconds (10 minutes). Default is
309
+ # 604,800 seconds (7 days).
298
310
  # @param [String] endpoint A URL locating the endpoint to which messages
299
311
  # should be pushed.
300
312
  # @param [String] autocreate Flag to control whether the topic will be
@@ -308,15 +320,7 @@ module Google
308
320
  # pubsub = Google::Cloud::Pubsub.new
309
321
  #
310
322
  # sub = pubsub.subscribe "my-topic", "my-topic-sub"
311
- # puts sub.name # => "my-topic-sub"
312
- #
313
- # @example The name is optional, and will be generated if not given.
314
- # require "google/cloud/pubsub"
315
- #
316
- # pubsub = Google::Cloud::Pubsub.new
317
- #
318
- # sub = pubsub.subscribe "my-topic"
319
- # puts sub.name # => "generated-sub-name"
323
+ # sub.name #=> "my-topic-sub"
320
324
  #
321
325
  # @example Wait 2 minutes for acknowledgement and push all to endpoint:
322
326
  # require "google/cloud/pubsub"
@@ -336,9 +340,11 @@ module Google
336
340
  # autocreate: true
337
341
  #
338
342
  def subscribe topic_name, subscription_name, deadline: nil,
339
- endpoint: nil, autocreate: nil
343
+ retain_acked: false, retention: nil, endpoint: nil,
344
+ autocreate: nil
340
345
  ensure_service!
341
- options = { deadline: deadline, endpoint: endpoint }
346
+ options = { deadline: deadline, retain_acked: retain_acked,
347
+ retention: retention, endpoint: endpoint }
342
348
  grpc = service.create_subscription topic_name,
343
349
  subscription_name, options
344
350
  Subscription.from_grpc grpc, service
@@ -346,7 +352,8 @@ module Google
346
352
  if autocreate
347
353
  create_topic topic_name
348
354
  return subscribe(topic_name, subscription_name,
349
- deadline: deadline, endpoint: endpoint,
355
+ deadline: deadline, retain_acked: retain_acked,
356
+ retention: retention, endpoint: endpoint,
350
357
  autocreate: false)
351
358
  end
352
359
  raise e
@@ -374,8 +381,8 @@ module Google
374
381
  #
375
382
  # pubsub = Google::Cloud::Pubsub.new
376
383
  #
377
- # subscription = pubsub.subscription "my-sub"
378
- # puts subscription.name
384
+ # sub = pubsub.subscription "my-sub"
385
+ # sub.name #=> "projects/my-project/subscriptions/my-sub"
379
386
  #
380
387
  # @example Skip the lookup against the service with `skip_lookup`:
381
388
  # require "google/cloud/pubsub"
@@ -383,8 +390,8 @@ module Google
383
390
  # pubsub = Google::Cloud::Pubsub.new
384
391
  #
385
392
  # # No API call is made to retrieve the subscription information.
386
- # subscription = pubsub.subscription "my-sub", skip_lookup: true
387
- # puts subscription.name
393
+ # sub = pubsub.subscription "my-sub", skip_lookup: true
394
+ # sub.name #=> "projects/my-project/subscriptions/my-sub"
388
395
  #
389
396
  def subscription subscription_name, project: nil, skip_lookup: nil
390
397
  ensure_service!
@@ -415,9 +422,9 @@ module Google
415
422
  #
416
423
  # pubsub = Google::Cloud::Pubsub.new
417
424
  #
418
- # subscriptions = pubsub.subscriptions
419
- # subscriptions.each do |subscription|
420
- # puts subscription.name
425
+ # subs = pubsub.subscriptions
426
+ # subs.each do |sub|
427
+ # puts sub.name
421
428
  # end
422
429
  #
423
430
  # @example Retrieve all subscriptions: (See {Subscription::List#all})
@@ -425,9 +432,9 @@ module Google
425
432
  #
426
433
  # pubsub = Google::Cloud::Pubsub.new
427
434
  #
428
- # subscriptions = pubsub.subscriptions
429
- # subscriptions.all do |subscription|
430
- # puts subscription.name
435
+ # subs = pubsub.subscriptions
436
+ # subs.all do |sub|
437
+ # puts sub.name
431
438
  # end
432
439
  #
433
440
  def subscriptions token: nil, max: nil
@@ -439,6 +446,46 @@ module Google
439
446
  alias_method :find_subscriptions, :subscriptions
440
447
  alias_method :list_subscriptions, :subscriptions
441
448
 
449
+
450
+ ##
451
+ # Retrieves a list of snapshots for the given project.
452
+ #
453
+ # @param [String] token A previously-returned page token representing
454
+ # part of the larger set of results to view.
455
+ # @param [Integer] max Maximum number of snapshots to return.
456
+ #
457
+ # @return [Array<Google::Cloud::Pubsub::Snapshot>] (See
458
+ # {Google::Cloud::Pubsub::Snapshot::List})
459
+ #
460
+ # @example
461
+ # require "google/cloud/pubsub"
462
+ #
463
+ # pubsub = Google::Cloud::Pubsub.new
464
+ #
465
+ # snapshots = pubsub.snapshots
466
+ # snapshots.each do |snapshot|
467
+ # puts snapshot.name
468
+ # end
469
+ #
470
+ # @example Retrieve all snapshots: (See {Snapshot::List#all})
471
+ # require "google/cloud/pubsub"
472
+ #
473
+ # pubsub = Google::Cloud::Pubsub.new
474
+ #
475
+ # snapshots = pubsub.snapshots
476
+ # snapshots.all do |snapshot|
477
+ # puts snapshot.name
478
+ # end
479
+ #
480
+ def snapshots token: nil, max: nil
481
+ ensure_service!
482
+ options = { token: token, max: max }
483
+ grpc = service.list_snapshots options
484
+ Snapshot::List.from_grpc grpc, service, max
485
+ end
486
+ alias_method :find_snapshots, :snapshots
487
+ alias_method :list_snapshots, :snapshots
488
+
442
489
  protected
443
490
 
444
491
  ##
@@ -41,7 +41,12 @@ module Google
41
41
 
42
42
  def channel
43
43
  require "grpc"
44
- GRPC::Core::Channel.new host, nil, chan_creds
44
+ GRPC::Core::Channel.new host, chan_args, chan_creds
45
+ end
46
+
47
+ def chan_args
48
+ { "grpc.max_send_message_length" => -1,
49
+ "grpc.max_receive_message_length" => -1 }
45
50
  end
46
51
 
47
52
  def chan_creds
@@ -208,12 +213,16 @@ module Google
208
213
  attributes: (options[:attributes] || {}).to_h
209
214
  end
210
215
  deadline = options[:deadline]
216
+ retain_acked = options[:retain_acked]
217
+ mrd = number_to_duration options[:retention]
211
218
 
212
219
  execute do
213
220
  subscriber.create_subscription name,
214
221
  topic,
215
222
  push_config: push_config,
216
223
  ack_deadline_seconds: deadline,
224
+ retain_acked_messages: retain_acked,
225
+ message_retention_duration: mrd,
217
226
  options: default_options
218
227
  end
219
228
  end
@@ -279,6 +288,63 @@ module Google
279
288
  end
280
289
  end
281
290
 
291
+ ##
292
+ # Lists snapshots by project.
293
+ def list_snapshots options = {}
294
+ call_options = default_options
295
+ if (token = options[:token])
296
+ call_options = Google::Gax::CallOptions.new kwargs: default_headers,
297
+ page_token: token
298
+ end
299
+
300
+ execute do
301
+ paged_enum = subscriber.list_snapshots project_path(options),
302
+ page_size: options[:max],
303
+ options: call_options
304
+
305
+ paged_enum.page.response
306
+ end
307
+ end
308
+
309
+ ##
310
+ # Creates a snapshot on a given subscription.
311
+ def create_snapshot subscription, snapshot_name
312
+ name = snapshot_path snapshot_name
313
+ execute do
314
+ subscriber.create_snapshot name,
315
+ subscription_path(subscription),
316
+ options: default_options
317
+ end
318
+ end
319
+
320
+ ##
321
+ # Deletes an existing snapshot.
322
+ # All pending messages in the snapshot are immediately dropped.
323
+ def delete_snapshot snapshot
324
+ execute do
325
+ subscriber.delete_snapshot snapshot_path(snapshot),
326
+ options: default_options
327
+ end
328
+ end
329
+
330
+ ##
331
+ # Adjusts the given subscription to a time or snapshot.
332
+ def seek subscription, time_or_snapshot
333
+ subscription = subscription_path(subscription)
334
+ execute do
335
+ if (time = time_to_timestamp time_or_snapshot)
336
+ subscriber.seek subscription, time: time, options: default_options
337
+ else
338
+ if time_or_snapshot.is_a? Snapshot
339
+ time_or_snapshot = time_or_snapshot.name
340
+ end
341
+ subscriber.seek subscription,
342
+ snapshot: snapshot_path(time_or_snapshot),
343
+ options: default_options
344
+ end
345
+ end
346
+ end
347
+
282
348
  def get_topic_policy topic_name, options = {}
283
349
  execute do
284
350
  publisher.get_iam_policy topic_path(topic_name, options),
@@ -346,6 +412,13 @@ module Google
346
412
  "#{project_path(options)}/subscriptions/#{subscription_name}"
347
413
  end
348
414
 
415
+ def snapshot_path snapshot_name, options = {}
416
+ if snapshot_name.nil? || snapshot_name.to_s.include?("/")
417
+ return snapshot_name
418
+ end
419
+ "#{project_path(options)}/snapshots/#{snapshot_name}"
420
+ end
421
+
349
422
  def inspect
350
423
  "#{self.class}(#{@project})"
351
424
  end
@@ -360,6 +433,27 @@ module Google
360
433
  Google::Gax::CallOptions.new kwargs: default_headers
361
434
  end
362
435
 
436
+ ##
437
+ # @private Get a Google::Protobuf::Timestamp object from a Time object.
438
+ def time_to_timestamp time
439
+ return nil if time.nil?
440
+ # Make sure to_time is supported.
441
+ return nil unless time.respond_to? :to_time
442
+ time = time.to_time
443
+ # Make sure we have a Time object.
444
+ # Rails' String#to_time returns nil if the string doesn't parse.
445
+ return nil unless time
446
+ Google::Protobuf::Timestamp.new seconds: time.to_i, nanos: time.nsec
447
+ end
448
+
449
+ def number_to_duration number
450
+ return nil if number.nil?
451
+
452
+ Google::Protobuf::Duration.new \
453
+ seconds: number.to_i,
454
+ nanos: (number.remainder(1) * 1000000000).round
455
+ end
456
+
363
457
  def execute
364
458
  yield
365
459
  rescue Google::Gax::GaxError => e