google-cloud-pubsub 1.9.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.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +18 -0
  3. data/AUTHENTICATION.md +177 -0
  4. data/CHANGELOG.md +538 -0
  5. data/CODE_OF_CONDUCT.md +40 -0
  6. data/CONTRIBUTING.md +188 -0
  7. data/EMULATOR.md +37 -0
  8. data/LICENSE +201 -0
  9. data/LOGGING.md +32 -0
  10. data/OVERVIEW.md +557 -0
  11. data/TROUBLESHOOTING.md +31 -0
  12. data/lib/google-cloud-pubsub.rb +139 -0
  13. data/lib/google/cloud/pubsub.rb +173 -0
  14. data/lib/google/cloud/pubsub/async_publisher.rb +399 -0
  15. data/lib/google/cloud/pubsub/async_publisher/batch.rb +309 -0
  16. data/lib/google/cloud/pubsub/batch_publisher.rb +99 -0
  17. data/lib/google/cloud/pubsub/convert.rb +91 -0
  18. data/lib/google/cloud/pubsub/credentials.rb +47 -0
  19. data/lib/google/cloud/pubsub/errors.rb +85 -0
  20. data/lib/google/cloud/pubsub/message.rb +158 -0
  21. data/lib/google/cloud/pubsub/policy.rb +187 -0
  22. data/lib/google/cloud/pubsub/project.rb +393 -0
  23. data/lib/google/cloud/pubsub/publish_result.rb +103 -0
  24. data/lib/google/cloud/pubsub/received_message.rb +297 -0
  25. data/lib/google/cloud/pubsub/retry_policy.rb +90 -0
  26. data/lib/google/cloud/pubsub/service.rb +514 -0
  27. data/lib/google/cloud/pubsub/snapshot.rb +202 -0
  28. data/lib/google/cloud/pubsub/snapshot/list.rb +178 -0
  29. data/lib/google/cloud/pubsub/subscriber.rb +399 -0
  30. data/lib/google/cloud/pubsub/subscriber/enumerator_queue.rb +54 -0
  31. data/lib/google/cloud/pubsub/subscriber/inventory.rb +166 -0
  32. data/lib/google/cloud/pubsub/subscriber/sequencer.rb +115 -0
  33. data/lib/google/cloud/pubsub/subscriber/stream.rb +401 -0
  34. data/lib/google/cloud/pubsub/subscriber/timed_unary_buffer.rb +231 -0
  35. data/lib/google/cloud/pubsub/subscription.rb +1279 -0
  36. data/lib/google/cloud/pubsub/subscription/list.rb +205 -0
  37. data/lib/google/cloud/pubsub/subscription/push_config.rb +244 -0
  38. data/lib/google/cloud/pubsub/topic.rb +934 -0
  39. data/lib/google/cloud/pubsub/topic/list.rb +171 -0
  40. data/lib/google/cloud/pubsub/v1.rb +17 -0
  41. data/lib/google/cloud/pubsub/v1/credentials.rb +41 -0
  42. data/lib/google/cloud/pubsub/v1/doc/google/iam/v1/iam_policy.rb +21 -0
  43. data/lib/google/cloud/pubsub/v1/doc/google/iam/v1/options.rb +21 -0
  44. data/lib/google/cloud/pubsub/v1/doc/google/iam/v1/policy.rb +21 -0
  45. data/lib/google/cloud/pubsub/v1/doc/google/protobuf/duration.rb +91 -0
  46. data/lib/google/cloud/pubsub/v1/doc/google/protobuf/empty.rb +29 -0
  47. data/lib/google/cloud/pubsub/v1/doc/google/protobuf/field_mask.rb +222 -0
  48. data/lib/google/cloud/pubsub/v1/doc/google/protobuf/timestamp.rb +113 -0
  49. data/lib/google/cloud/pubsub/v1/doc/google/pubsub/v1/pubsub.rb +833 -0
  50. data/lib/google/cloud/pubsub/v1/doc/google/type/expr.rb +19 -0
  51. data/lib/google/cloud/pubsub/v1/publisher_client.rb +928 -0
  52. data/lib/google/cloud/pubsub/v1/publisher_client_config.json +120 -0
  53. data/lib/google/cloud/pubsub/v1/subscriber_client.rb +1466 -0
  54. data/lib/google/cloud/pubsub/v1/subscriber_client_config.json +153 -0
  55. data/lib/google/cloud/pubsub/version.rb +24 -0
  56. data/lib/google/pubsub/v1/pubsub_pb.rb +269 -0
  57. data/lib/google/pubsub/v1/pubsub_services_pb.rb +215 -0
  58. metadata +337 -0
@@ -0,0 +1,32 @@
1
+ # Enabling gRPC Logging
2
+
3
+ To enable logging for this library, set the logger for the underlying
4
+ [gRPC](https://github.com/grpc/grpc/tree/master/src/ruby) library. The logger
5
+ that you set may be a Ruby stdlib
6
+ [`Logger`](https://ruby-doc.org/stdlib-2.5.0/libdoc/logger/rdoc/Logger.html) as
7
+ shown below, or a
8
+ [`Google::Cloud::Logging::Logger`](https://googleapis.dev/ruby/google-cloud-logging/latest)
9
+ that will write logs to [Stackdriver
10
+ Logging](https://cloud.google.com/logging/). See
11
+ [grpc/logconfig.rb](https://github.com/grpc/grpc/blob/master/src/ruby/lib/grpc/logconfig.rb)
12
+ and the gRPC
13
+ [spec_helper.rb](https://github.com/grpc/grpc/blob/master/src/ruby/spec/spec_helper.rb)
14
+ for additional information.
15
+
16
+ Configuring a Ruby stdlib logger:
17
+
18
+ ```ruby
19
+ require "logger"
20
+
21
+ module MyLogger
22
+ LOGGER = Logger.new $stderr, level: Logger::WARN
23
+ def logger
24
+ LOGGER
25
+ end
26
+ end
27
+
28
+ # Define a gRPC module-level logger method before grpc/logconfig.rb loads.
29
+ module GRPC
30
+ extend MyLogger
31
+ end
32
+ ```
@@ -0,0 +1,557 @@
1
+ # Google Cloud Pub/Sub
2
+
3
+ Google Cloud Pub/Sub is designed to provide reliable, many-to-many, asynchronous
4
+ messaging between applications. Publisher applications can send messages to a
5
+ "topic" and other applications can subscribe to that topic to receive the
6
+ messages. By decoupling senders and receivers, Google Cloud Pub/Sub allows
7
+ developers to communicate between independently written applications.
8
+
9
+ The goal of google-cloud is to provide an API that is comfortable to Rubyists.
10
+ Your authentication credentials are detected automatically in Google Cloud
11
+ Platform (GCP), including Google Compute Engine (GCE), Google Kubernetes Engine
12
+ (GKE), Google App Engine (GAE), Google Cloud Functions (GCF) and Cloud Run. In
13
+ other environments you can configure authentication easily, either directly in
14
+ your code or via environment variables. Read more about the options for
15
+ connecting in the {file:AUTHENTICATION.md Authentication Guide}.
16
+
17
+ ```ruby
18
+ require "google/cloud/pubsub"
19
+
20
+ pubsub = Google::Cloud::PubSub.new
21
+
22
+ topic = pubsub.topic "my-topic"
23
+ topic.publish "task completed"
24
+ ```
25
+
26
+ To learn more about Pub/Sub, read the [Google Cloud Pub/Sub Overview
27
+ ](https://cloud.google.com/pubsub/overview).
28
+
29
+ ## Retrieving Topics
30
+
31
+ A Topic is a named resource to which messages are sent by publishers. A Topic is
32
+ found by its name. (See {Google::Cloud::PubSub::Project#topic Project#topic})
33
+
34
+ ```ruby
35
+ require "google/cloud/pubsub"
36
+
37
+ pubsub = Google::Cloud::PubSub.new
38
+ topic = pubsub.topic "my-topic"
39
+ ```
40
+
41
+ ## Creating a Topic
42
+
43
+ A Topic is created from a Project. (See
44
+ {Google::Cloud::PubSub::Project#create_topic Project#create_topic})
45
+
46
+ ```ruby
47
+ require "google/cloud/pubsub"
48
+
49
+ pubsub = Google::Cloud::PubSub.new
50
+ topic = pubsub.create_topic "my-topic"
51
+ ```
52
+
53
+ ## Retrieving Subscriptions
54
+
55
+ A Subscription is a named resource representing the stream of messages from a
56
+ single, specific Topic, to be delivered to the subscribing application. A
57
+ Subscription is found by its name. (See
58
+ {Google::Cloud::PubSub::Topic#subscription Topic#subscription})
59
+
60
+ ```ruby
61
+ require "google/cloud/pubsub"
62
+
63
+ pubsub = Google::Cloud::PubSub.new
64
+
65
+ topic = pubsub.topic "my-topic"
66
+ subscription = topic.subscription "my-topic-subscription"
67
+ puts subscription.name
68
+ ```
69
+
70
+ ## Creating a Subscription
71
+
72
+ A Subscription is created from a Topic. (See
73
+ {Google::Cloud::PubSub::Topic#subscribe Topic#subscribe})
74
+
75
+ ```ruby
76
+ require "google/cloud/pubsub"
77
+
78
+ pubsub = Google::Cloud::PubSub.new
79
+
80
+ topic = pubsub.topic "my-topic"
81
+ sub = topic.subscribe "my-topic-sub"
82
+ puts sub.name # => "my-topic-sub"
83
+ ```
84
+
85
+ The subscription can be created that specifies the number of seconds to wait to
86
+ be acknowledged as well as an endpoint URL to push the messages to:
87
+
88
+ ```ruby
89
+ require "google/cloud/pubsub"
90
+
91
+ pubsub = Google::Cloud::PubSub.new
92
+
93
+ topic = pubsub.topic "my-topic"
94
+ sub = topic.subscribe "my-topic-sub",
95
+ deadline: 120,
96
+ endpoint: "https://example.com/push"
97
+ ```
98
+
99
+ ## Publishing Messages
100
+
101
+ Messages are published to a topic. Any message published to a topic without a
102
+ subscription will be lost. Ensure the topic has a subscription before
103
+ publishing. (See {Google::Cloud::PubSub::Topic#publish Topic#publish})
104
+
105
+ ```ruby
106
+ require "google/cloud/pubsub"
107
+
108
+ pubsub = Google::Cloud::PubSub.new
109
+
110
+ topic = pubsub.topic "my-topic"
111
+ msg = topic.publish "task completed"
112
+ ```
113
+
114
+ Messages can also be published with attributes:
115
+
116
+ ```ruby
117
+ require "google/cloud/pubsub"
118
+
119
+ pubsub = Google::Cloud::PubSub.new
120
+
121
+ topic = pubsub.topic "my-topic"
122
+ msg = topic.publish "task completed",
123
+ foo: :bar,
124
+ this: :that
125
+ ```
126
+
127
+ Messages can also be published in batches asynchronously using `publish_async`.
128
+ (See {Google::Cloud::PubSub::Topic#publish_async Topic#publish_async} and
129
+ {Google::Cloud::PubSub::AsyncPublisher AsyncPublisher})
130
+
131
+ ```ruby
132
+ require "google/cloud/pubsub"
133
+
134
+ pubsub = Google::Cloud::PubSub.new
135
+
136
+ topic = pubsub.topic "my-topic"
137
+ topic.publish_async "task completed" do |result|
138
+ if result.succeeded?
139
+ log_publish_success result.data
140
+ else
141
+ log_publish_failure result.data, result.error
142
+ end
143
+ end
144
+
145
+ topic.async_publisher.stop.wait!
146
+ ```
147
+
148
+ Or multiple messages can be published in batches at the same time by passing a
149
+ block to `publish`. (See {Google::Cloud::PubSub::BatchPublisher BatchPublisher})
150
+
151
+ ```ruby
152
+ require "google/cloud/pubsub"
153
+
154
+ pubsub = Google::Cloud::PubSub.new
155
+
156
+ topic = pubsub.topic "my-topic"
157
+ msgs = topic.publish do |batch|
158
+ batch.publish "task 1 completed", foo: :bar
159
+ batch.publish "task 2 completed", foo: :baz
160
+ batch.publish "task 3 completed", foo: :bif
161
+ end
162
+ ```
163
+
164
+ ## Receiving Messages
165
+
166
+ Messages can be streamed from a subscription with a subscriber object that is
167
+ created using `listen`. (See {Google::Cloud::PubSub::Subscription#listen
168
+ Subscription#listen} and {Google::Cloud::PubSub::Subscriber Subscriber})
169
+
170
+ ```ruby
171
+ require "google/cloud/pubsub"
172
+
173
+ pubsub = Google::Cloud::PubSub.new
174
+
175
+ sub = pubsub.subscription "my-topic-sub"
176
+
177
+ subscriber = sub.listen do |received_message|
178
+ # process message
179
+ received_message.acknowledge!
180
+ end
181
+
182
+ # Start background threads that will call the block passed to listen.
183
+ subscriber.start
184
+
185
+ # Shut down the subscriber when ready to stop receiving messages.
186
+ subscriber.stop.wait!
187
+ ```
188
+
189
+ Messages also can be pulled directly in a one-time operation. (See
190
+ {Google::Cloud::PubSub::Subscription#pull Subscription#pull})
191
+
192
+ ```ruby
193
+ require "google/cloud/pubsub"
194
+
195
+ pubsub = Google::Cloud::PubSub.new
196
+
197
+ sub = pubsub.subscription "my-topic-sub"
198
+ received_messages = sub.pull
199
+ ```
200
+
201
+ A maximum number of messages to pull can be specified:
202
+
203
+ ```ruby
204
+ require "google/cloud/pubsub"
205
+
206
+ pubsub = Google::Cloud::PubSub.new
207
+
208
+ sub = pubsub.subscription "my-topic-sub"
209
+ received_messages = sub.pull max: 10
210
+ ```
211
+
212
+ ## Acknowledging a Message
213
+
214
+ Messages that are received can be acknowledged in Pub/Sub, marking the message
215
+ to be removed so it cannot be pulled again.
216
+
217
+ A Message that can be acknowledged is called a ReceivedMessage. ReceivedMessages
218
+ can be acknowledged one at a time: (See
219
+ {Google::Cloud::PubSub::ReceivedMessage#acknowledge!
220
+ ReceivedMessage#acknowledge!})
221
+
222
+ ```ruby
223
+ require "google/cloud/pubsub"
224
+
225
+ pubsub = Google::Cloud::PubSub.new
226
+
227
+ sub = pubsub.subscription "my-topic-sub"
228
+
229
+ subscriber = sub.listen do |received_message|
230
+ # process message
231
+ received_message.acknowledge!
232
+ end
233
+
234
+ # Start background threads that will call the block passed to listen.
235
+ subscriber.start
236
+
237
+ # Shut down the subscriber when ready to stop receiving messages.
238
+ subscriber.stop.wait!
239
+ ```
240
+
241
+ Or, multiple messages can be acknowledged in a single API call: (See
242
+ {Google::Cloud::PubSub::Subscription#acknowledge Subscription#acknowledge})
243
+
244
+ ```ruby
245
+ require "google/cloud/pubsub"
246
+
247
+ pubsub = Google::Cloud::PubSub.new
248
+
249
+ sub = pubsub.subscription "my-topic-sub"
250
+ received_messages = sub.pull
251
+ sub.acknowledge received_messages
252
+ ```
253
+
254
+ ## Modifying a Deadline
255
+
256
+ A message must be acknowledged after it is pulled, or Pub/Sub will mark the
257
+ message for redelivery. The message acknowledgement deadline can delayed if more
258
+ time is needed. This will allow more time to process the message before the
259
+ message is marked for redelivery. (See
260
+ {Google::Cloud::PubSub::ReceivedMessage#modify_ack_deadline!
261
+ ReceivedMessage#modify_ack_deadline!})
262
+
263
+ ```ruby
264
+ require "google/cloud/pubsub"
265
+
266
+ pubsub = Google::Cloud::PubSub.new
267
+
268
+ sub = pubsub.subscription "my-topic-sub"
269
+ subscriber = sub.listen do |received_message|
270
+ puts received_message.message.data
271
+
272
+ # Delay for 2 minutes
273
+ received_message.modify_ack_deadline! 120
274
+ end
275
+
276
+ # Start background threads that will call the block passed to listen.
277
+ subscriber.start
278
+
279
+ # Shut down the subscriber when ready to stop receiving messages.
280
+ subscriber.stop.wait!
281
+ ```
282
+
283
+ The message can also be made available for immediate redelivery:
284
+
285
+ ```ruby
286
+ require "google/cloud/pubsub"
287
+
288
+ pubsub = Google::Cloud::PubSub.new
289
+
290
+ sub = pubsub.subscription "my-topic-sub"
291
+ subscriber = sub.listen do |received_message|
292
+ puts received_message.message.data
293
+
294
+ # Mark for redelivery
295
+ received_message.reject!
296
+ end
297
+
298
+ # Start background threads that will call the block passed to listen.
299
+ subscriber.start
300
+
301
+ # Shut down the subscriber when ready to stop receiving messages.
302
+ subscriber.stop.wait!
303
+ ```
304
+
305
+ Multiple messages can be delayed or made available for immediate redelivery:
306
+ (See {Google::Cloud::PubSub::Subscription#modify_ack_deadline
307
+ Subscription#modify_ack_deadline})
308
+
309
+ ```ruby
310
+ require "google/cloud/pubsub"
311
+
312
+ pubsub = Google::Cloud::PubSub.new
313
+
314
+ sub = pubsub.subscription "my-topic-sub"
315
+ received_messages = sub.pull
316
+ sub.modify_ack_deadline 120, received_messages
317
+ ```
318
+
319
+ ## Using Ordering Keys
320
+
321
+ Google Cloud Pub/Sub ordering keys provide the ability to ensure related
322
+ messages are sent to subscribers in the order in which they were published.
323
+ Messages can be tagged with an ordering key, a string that identifies related
324
+ messages for which publish order should be respected. The service guarantees
325
+ that, for a given ordering key and publisher, messages are sent to subscribers
326
+ in the order in which they were published. Ordering does not require sacrificing
327
+ high throughput or scalability, as the service automatically distributes
328
+ messages for different ordering keys across subscribers.
329
+
330
+ Note: At the time of this release, ordering keys are not yet publicly enabled
331
+ and requires special project enablements.
332
+
333
+ ### Publishing Ordered Messages
334
+
335
+ To use ordering keys when publishing messages, a call to
336
+ {Google::Cloud::PubSub::Topic#enable_message_ordering!
337
+ Topic#enable_message_ordering!} must be made and the `ordering_key` argument
338
+ must be provided when calling {Google::Cloud::PubSub::Topic#publish_async
339
+ Topic#publish_async}.
340
+
341
+ ```ruby
342
+ require "google/cloud/pubsub"
343
+
344
+ pubsub = Google::Cloud::PubSub.new
345
+
346
+ topic = pubsub.topic "my-ordered-topic"
347
+
348
+ # Ensure that message ordering is enabled.
349
+ topic.enable_message_ordering!
350
+
351
+ # Publish an ordered message with an ordering key.
352
+ topic.publish_async "task completed",
353
+ ordering_key: "task-key"
354
+
355
+ # Shut down the publisher when ready to stop publishing messages.
356
+ topic.async_publisher.stop.wait!
357
+ ```
358
+
359
+ ### Handling errors with Ordered Keys
360
+
361
+ Ordered messages that fail to publish to the Pub/Sub API due to error will put
362
+ the `ordering_key` in a failed state, and future calls to
363
+ {Google::Cloud::PubSub::Topic#publish_async Topic#publish_async} with the
364
+ `ordering_key` will raise {Google::Cloud::PubSub::OrderingKeyError
365
+ OrderingKeyError}. To allow future messages with the `ordering_key` to be
366
+ published, the `ordering_key` must be passed to
367
+ {Google::Cloud::PubSub::Topic#resume_publish Topic#resume_publish}.
368
+
369
+ ### Receiving Ordered Messages
370
+
371
+ To use ordering keys when subscribing to messages, the subscription must be
372
+ created with message ordering enabled (See
373
+ {Google::Cloud::PubSub::Topic#subscribe Topic#subscribe} and
374
+ {Google::Cloud::PubSub::Subscription#message_ordering?
375
+ Subscription#message_ordering?}) before calling
376
+ {Google::Cloud::PubSub::Subscription#listen Subscription#listen}. When enabled,
377
+ the subscriber will deliver messages with the same `ordering_key` in the order
378
+ they were published.
379
+
380
+ ```ruby
381
+ require "google/cloud/pubsub"
382
+
383
+ pubsub = Google::Cloud::PubSub.new
384
+
385
+ sub = pubsub.subscription "my-ordered-topic-sub"
386
+ sub.message_ordering? #=> true
387
+
388
+ subscriber = sub.listen do |received_message|
389
+ # Messsages with the same ordering_key are received
390
+ # in the order in which they were published.
391
+ received_message.acknowledge!
392
+ end
393
+
394
+ # Start background threads that will call block passed to listen.
395
+ subscriber.start
396
+
397
+ # Shut down the subscriber when ready to stop receiving messages.
398
+ subscriber.stop.wait!
399
+ ```
400
+
401
+ ## Minimizing API calls before receiving and acknowledging messages
402
+
403
+ A subscription object can be created without making any API calls by providing
404
+ the `skip_lookup` argument to {Google::Cloud::PubSub::Project#subscription
405
+ Project#subscription} or {Google::Cloud::PubSub::Topic#subscription
406
+ Topic#subscription}. A subscriber object can also be created without an API call
407
+ by providing the `deadline` optional argument to
408
+ {Google::Cloud::PubSub::Subscription#listen Subscription#listen}:
409
+
410
+ ```ruby
411
+ require "google/cloud/pubsub"
412
+
413
+ pubsub = Google::Cloud::PubSub.new
414
+
415
+ # No API call is made to retrieve the subscription resource.
416
+ sub = pubsub.subscription "my-topic-sub", skip_lookup: true
417
+
418
+ # No API call is made to retrieve the subscription deadline.
419
+ subscriber = sub.listen deadline: 60 do |received_message|
420
+ # process message
421
+ received_message.acknowledge!
422
+ end
423
+
424
+ # Start background threads that will call block passed to listen.
425
+ subscriber.start
426
+
427
+ # Shut down the subscriber when ready to stop receiving messages.
428
+ subscriber.stop.wait!
429
+ ```
430
+
431
+ Skipping API calls may be used to avoid `Google::Cloud::PermissionDeniedError`
432
+ if your account has limited access to the Pub/Sub API. In particular, the role
433
+ `roles/pubsub.subscriber` does not have the permission
434
+ `pubsub.subscriptions.get`, which is required to retrieve a subscription
435
+ resource. See [Access Control -
436
+ Roles](https://cloud.google.com/pubsub/docs/access-control#tbl_roles) for the
437
+ complete list of Pub/Sub roles and permissions.
438
+
439
+ ## Creating a snapshot and using seek
440
+
441
+ You can create a snapshot to retain the existing backlog on a subscription. The
442
+ snapshot will hold the messages in the subscription's backlog that are
443
+ unacknowledged upon the successful completion of the `create_snapshot`
444
+ operation.
445
+
446
+ Later, you can use `seek` to reset the subscription's backlog to the snapshot.
447
+
448
+ (See {Google::Cloud::PubSub::Subscription#create_snapshot
449
+ Subscription#create_snapshot} and {Google::Cloud::PubSub::Subscription#seek
450
+ Subscription#seek})
451
+
452
+ ```ruby
453
+ require "google/cloud/pubsub"
454
+
455
+ pubsub = Google::Cloud::PubSub.new
456
+
457
+ sub = pubsub.subscription "my-topic-sub"
458
+
459
+ snapshot = sub.create_snapshot
460
+
461
+ received_messages = sub.pull
462
+ sub.acknowledge received_messages
463
+
464
+ sub.seek snapshot
465
+ ```
466
+
467
+ ## Listening for Messages
468
+
469
+ A subscriber object can be created using `listen`, which streams messages from
470
+ the backend and processes them as they are received. (See
471
+ {Google::Cloud::PubSub::Subscription#listen Subscription#listen} and
472
+ {Google::Cloud::PubSub::Subscriber Subscriber})
473
+
474
+ ```ruby
475
+ require "google/cloud/pubsub"
476
+
477
+ pubsub = Google::Cloud::PubSub.new
478
+
479
+ sub = pubsub.subscription "my-topic-sub"
480
+
481
+ subscriber = sub.listen do |received_message|
482
+ # process message
483
+ received_message.acknowledge!
484
+ end
485
+
486
+ # Start background threads that will call the block passed to listen.
487
+ subscriber.start
488
+
489
+ # Shut down the subscriber when ready to stop receiving messages.
490
+ subscriber.stop.wait!
491
+ ```
492
+
493
+ The subscriber object can be configured to control the number of concurrent
494
+ streams to open, the number of received messages to be collected, and the number
495
+ of threads each stream opens for concurrent calls made to handle the received
496
+ messages.
497
+
498
+ ```ruby
499
+ require "google/cloud/pubsub"
500
+
501
+ pubsub = Google::Cloud::PubSub.new
502
+
503
+ sub = pubsub.subscription "my-topic-sub"
504
+
505
+ subscriber = sub.listen threads: { callback: 16 } do |received_message|
506
+ # store the message somewhere before acknowledging
507
+ store_in_backend received_message.data # takes a few seconds
508
+ received_message.acknowledge!
509
+ end
510
+
511
+ # Start background threads that will call the block passed to listen.
512
+ subscriber.start
513
+ ```
514
+
515
+ ## Working Across Projects
516
+
517
+ All calls to the Pub/Sub service use the same project and credentials provided
518
+ to the {Google::Cloud::PubSub.new PubSub.new} method. However, it is common to
519
+ reference topics or subscriptions in other projects, which can be achieved by
520
+ using the `project` option. The main credentials must have permissions to the
521
+ topics and subscriptions in other projects.
522
+
523
+ ```ruby
524
+ require "google/cloud/pubsub"
525
+
526
+ pubsub = Google::Cloud::PubSub.new # my-project
527
+
528
+ # Get a topic in the current project
529
+ my_topic = pubsub.topic "my-topic"
530
+ my_topic.name #=> "projects/my-project/topics/my-topic"
531
+ # Get a topic in another project
532
+ other_topic = pubsub.topic "other-topic", project: "other-project-id"
533
+ other_topic.name #=> "projects/other-project-id/topics/other-topic"
534
+ ```
535
+
536
+ It is possible to create a subscription in the current project that pulls
537
+ from a topic in another project:
538
+
539
+ ```ruby
540
+ require "google/cloud/pubsub"
541
+
542
+ pubsub = Google::Cloud::PubSub.new # my-project
543
+
544
+ # Get a topic in another project
545
+ topic = pubsub.topic "other-topic", project: "other-project-id"
546
+ # Create a subscription in the current project that pulls from
547
+ # the topic in another project
548
+ sub = topic.subscribe "my-sub"
549
+ sub.name #=> "projects/my-project/subscriptions/my-sub"
550
+ sub.topic.name #=> "projects/other-project-id/topics/other-topic"
551
+ ```
552
+
553
+ ## Additional information
554
+
555
+ Google Cloud Pub/Sub can be configured to use an emulator or to enable gRPC's
556
+ logging. To learn more, see the {file:EMULATOR.md Emulator guide} and
557
+ {file:LOGGING.md Logging guide}.