google-cloud-pubsub 2.1.1 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 450987f2e0c301c5b43af3211dda2c6698dfa76a29076c47dc9a9690698fa9df
4
- data.tar.gz: 84f19d7d3aacaa290e7364558ebd29795f3fce76783254df8d2df43b653e02f8
3
+ metadata.gz: f6636ac65229c0dc438c63fa9aebda474396701364bfbea7e5da460ceea50a26
4
+ data.tar.gz: a0c0cafbbaf4083c1141d851dc6cecb8cb70bc01df940a139fe21d057aa2fb97
5
5
  SHA512:
6
- metadata.gz: 7b10cd6edeb5cf4d352028f58a233eb8f56f4de079ed4f2b344cb930750efe16758c736bb160635a8e019083ddf04fe01255175f18467d35a46966e9d1c19787
7
- data.tar.gz: b67f8da4a9c0b73fa065a9364773dbaaa2682d993163f9bac62fab849b00178aaeab258cc0d4962e74106535be540ec2e42cfb6b888d973b4b97c06efb217f32
6
+ metadata.gz: a187e9935196b66d4be65c7cf7b34148de36197f9e2c5e9144ccc9f78652370d7a441b33e14a002133b05aa6565cc38998912277e8896d81178bf5712ce9df8c
7
+ data.tar.gz: ee801f9d5959f5e2a38ccf13beaac930ca4629c81a268b627a8bacc7ad9ce430581fd690100fa5ef57b4fa5e20e3c5f40d72e905ce2535d978398f03112a48eb
data/CHANGELOG.md CHANGED
@@ -1,5 +1,93 @@
1
1
  # Release History
2
2
 
3
+ ### 2.7.0 / 2021-06-15
4
+
5
+ #### Features
6
+
7
+ * Add Publisher Flow Control
8
+ * Add flow_control to async options in Project#create_topic and Project#topic
9
+ * Add FlowControlLimitError
10
+
11
+ #### Bug Fixes
12
+
13
+ * Fix Project#schema and #schemas to return full resource
14
+ * Include schema definition in default return values.
15
+ * Fix Schema#definition to return nil instead of empty string when not present.
16
+
17
+ ### 2.6.1 / 2021-04-28
18
+
19
+ #### Bug Fixes
20
+
21
+ * Add final flush of pending requests to Subscriber#wait!
22
+ * fix(pubsub): Add final flush of pending requests to Subscriber#wait!
23
+
24
+ ### 2.6.0 / 2021-04-19
25
+
26
+ #### Features
27
+
28
+ * Add ordering_key to Topic#publish
29
+ * Add ordering_key to BatchPublisher#publish
30
+
31
+ #### Documentation
32
+
33
+ * The immediate: false option is recommended to avoid adverse impacts on the performance of pull operations ([#11153](https://www.github.com/googleapis/google-cloud-ruby/issues/11153))
34
+ * Update Subscription#pull docs and samples to recommend immediate: false
35
+
36
+ ### 2.5.0 / 2021-04-01
37
+
38
+ #### Features
39
+
40
+ * Add Schema support
41
+ * Add Schema
42
+ * Add Project#create_schema
43
+ * Add Project#schema
44
+ * Add Project#schemas (Schema::List)
45
+ * Add Project#valid_schema?
46
+ * Add schema options to Project#create_topic
47
+ * Add Topic#schema_name
48
+ * Add Topic#message_encoding
49
+ * Add Topic#message_encoding_binary?
50
+ * Add Topic#message_encoding_json?
51
+
52
+ ### 2.4.0 / 2021-03-10
53
+
54
+ #### Features
55
+
56
+ * Drop support for Ruby 2.4 and add support for Ruby 3.0
57
+
58
+ ### 2.3.2 / 2021-02-08
59
+
60
+ #### Bug Fixes
61
+
62
+ * Fix project option in Project#topic and Project#subscription
63
+ * Ensure that project option is used when skip_lookup is false.
64
+ * Improve documentation of topic_name, subscription_name and snapshot_name.
65
+
66
+ ### 2.3.1 / 2021-01-13
67
+
68
+ #### Bug Fixes
69
+
70
+ * Update Subscription#retry_policy=
71
+ * Remove conditional RPC to fetch full resource before update.
72
+
73
+ ### 2.3.0 / 2020-11-18
74
+
75
+ #### Features
76
+
77
+ * Add inventory.use_legacy_flow_control to listen options
78
+ * Add inventory.use_legacy_flow_control to Subscription#listen options
79
+ * Add Subscriber#use_legacy_flow_control?
80
+
81
+ #### Documentation
82
+
83
+ * Remove EXPERIMENTAL label from RetryPolicy docs
84
+
85
+ ### 2.2.0 / 2020-11-11
86
+
87
+ #### Features
88
+
89
+ * Add Subscription#remove_dead_letter_policy
90
+
3
91
  ### 2.1.1 / 2020-10-26
4
92
 
5
93
  #### Documentation
data/CONTRIBUTING.md CHANGED
@@ -24,7 +24,7 @@ be able to accept your pull requests.
24
24
  In order to use the google-cloud-pubsub console and run the project's tests,
25
25
  there is a small amount of setup:
26
26
 
27
- 1. Install Ruby. google-cloud-pubsub requires Ruby 2.4+. You may choose to
27
+ 1. Install Ruby. google-cloud-pubsub requires Ruby 2.5+. You may choose to
28
28
  manage your Ruby and gem installations with [RVM](https://rvm.io/),
29
29
  [rbenv](https://github.com/rbenv/rbenv), or
30
30
  [chruby](https://github.com/postmodern/chruby).
@@ -45,7 +45,7 @@ there is a small amount of setup:
45
45
 
46
46
  ```sh
47
47
  $ cd google-cloud-pubsub/
48
- $ bundle exec rake bundleupdate
48
+ $ bundle install
49
49
  ```
50
50
 
51
51
  ## Console
@@ -119,15 +119,14 @@ If you alter an example's title, you may encounter breaking tests.
119
119
  ### Pub/Sub Acceptance Tests
120
120
 
121
121
  The Pub/Sub acceptance tests interact with the live service API. Follow the
122
- instructions in the {file:AUTHENTICATION.md Authentication guide} for enabling
122
+ instructions in the {file:AUTHENTICATION.md Authentication Guide} for enabling
123
123
  the Pub/Sub API. Occasionally, some API features may not yet be generally
124
124
  available, making it difficult for some contributors to successfully run the
125
125
  entire acceptance test suite. However, please ensure that you do successfully
126
126
  run acceptance tests for any code areas covered by your pull request.
127
127
 
128
128
  To run the acceptance tests, first create and configure a project in the Google
129
- Developers Console, as described in the {file:AUTHENTICATION.md Authentication
130
- guide}. Be sure to download the JSON KEY file. Make note of the PROJECT_ID and
129
+ Developers Console, as described in the {file:AUTHENTICATION.md Authentication Guide}. Be sure to download the JSON KEY file. Make note of the PROJECT_ID and
131
130
  the KEYFILE location on your system.
132
131
 
133
132
  Before you can run the Pub/Sub acceptance tests, you must first create indexes
data/LOGGING.md CHANGED
@@ -3,7 +3,7 @@
3
3
  To enable logging for this library, set the logger for the underlying
4
4
  [gRPC](https://github.com/grpc/grpc/tree/master/src/ruby) library. The logger
5
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
6
+ [`Logger`](https://ruby-doc.org/stdlib/libdoc/logger/rdoc/Logger.html) as
7
7
  shown below, or a
8
8
  [`Google::Cloud::Logging::Logger`](https://googleapis.dev/ruby/google-cloud-logging/latest)
9
9
  that will write logs to [Stackdriver
data/OVERVIEW.md CHANGED
@@ -205,13 +205,16 @@ sleep
205
205
  Messages also can be pulled directly in a one-time operation. (See
206
206
  {Google::Cloud::PubSub::Subscription#pull Subscription#pull})
207
207
 
208
+ The `immediate: false` option is recommended to avoid adverse impacts on the
209
+ performance of pull operations.
210
+
208
211
  ```ruby
209
212
  require "google/cloud/pubsub"
210
213
 
211
214
  pubsub = Google::Cloud::PubSub.new
212
215
 
213
216
  sub = pubsub.subscription "my-topic-sub"
214
- received_messages = sub.pull
217
+ received_messages = sub.pull immediate: false
215
218
  ```
216
219
 
217
220
  A maximum number of messages to pull can be specified:
@@ -222,7 +225,7 @@ require "google/cloud/pubsub"
222
225
  pubsub = Google::Cloud::PubSub.new
223
226
 
224
227
  sub = pubsub.subscription "my-topic-sub"
225
- received_messages = sub.pull max: 10
228
+ received_messages = sub.pull immediate: false, max: 10
226
229
  ```
227
230
 
228
231
  ## Acknowledging a Message
@@ -263,7 +266,7 @@ require "google/cloud/pubsub"
263
266
  pubsub = Google::Cloud::PubSub.new
264
267
 
265
268
  sub = pubsub.subscription "my-topic-sub"
266
- received_messages = sub.pull
269
+ received_messages = sub.pull immediate: false
267
270
  sub.acknowledge received_messages
268
271
  ```
269
272
 
@@ -328,7 +331,7 @@ require "google/cloud/pubsub"
328
331
  pubsub = Google::Cloud::PubSub.new
329
332
 
330
333
  sub = pubsub.subscription "my-topic-sub"
331
- received_messages = sub.pull
334
+ received_messages = sub.pull immediate: false
332
335
  sub.modify_ack_deadline 120, received_messages
333
336
  ```
334
337
 
@@ -474,7 +477,7 @@ sub = pubsub.subscription "my-topic-sub"
474
477
 
475
478
  snapshot = sub.create_snapshot
476
479
 
477
- received_messages = sub.pull
480
+ received_messages = sub.pull immediate: false
478
481
  sub.acknowledge received_messages
479
482
 
480
483
  sub.seek snapshot
@@ -521,5 +524,5 @@ sub.topic.name #=> "projects/other-project-id/topics/other-topic"
521
524
  ## Additional information
522
525
 
523
526
  Google Cloud Pub/Sub can be configured to use an emulator or to enable gRPC's
524
- logging. To learn more, see the {file:EMULATOR.md Emulator guide} and
527
+ logging. To learn more, see the {file:EMULATOR.md Emulator guide}} and
525
528
  {file:LOGGING.md Logging guide}.
@@ -33,8 +33,6 @@ module Google
33
33
  # See {file:OVERVIEW.md Google Cloud Pub/Sub Overview}.
34
34
  #
35
35
  module PubSub
36
- # rubocop:disable Metrics/AbcSize
37
-
38
36
  ##
39
37
  # Creates a new object for connecting to the Pub/Sub service.
40
38
  # Each call creates a new connection.
@@ -110,8 +108,6 @@ module Google
110
108
  PubSub::Project.new service
111
109
  end
112
110
 
113
- # rubocop:enable Metrics/AbcSize
114
-
115
111
  ##
116
112
  # Configure the Google Cloud PubSub library.
117
113
  #
@@ -16,6 +16,7 @@
16
16
  require "monitor"
17
17
  require "concurrent"
18
18
  require "google/cloud/pubsub/errors"
19
+ require "google/cloud/pubsub/flow_controller"
19
20
  require "google/cloud/pubsub/async_publisher/batch"
20
21
  require "google/cloud/pubsub/publish_result"
21
22
  require "google/cloud/pubsub/service"
@@ -44,8 +45,8 @@ module Google
44
45
  #
45
46
  # topic.async_publisher.stop!
46
47
  #
47
- # @attr_reader [String] topic_name The name of the topic the messages are published to. In the form of
48
- # "/projects/project-identifier/topics/topic-name".
48
+ # @attr_reader [String] topic_name The name of the topic the messages are published to. The value is a
49
+ # fully-qualified topic name in the form `projects/{project_id}/topics/{topic_id}`.
49
50
  # @attr_reader [Integer] max_bytes The maximum size of messages to be collected before the batch is published.
50
51
  # Default is 1,000,000 (1MB).
51
52
  # @attr_reader [Integer] max_messages The maximum number of messages to be collected before the batch is
@@ -59,16 +60,27 @@ module Google
59
60
  class AsyncPublisher
60
61
  include MonitorMixin
61
62
 
62
- attr_reader :topic_name, :max_bytes, :max_messages, :interval,
63
- :publish_threads, :callback_threads
63
+ attr_reader :topic_name
64
+ attr_reader :max_bytes
65
+ attr_reader :max_messages
66
+ attr_reader :interval
67
+ attr_reader :publish_threads
68
+ attr_reader :callback_threads
69
+ attr_reader :flow_control
64
70
  ##
65
71
  # @private Implementation accessors
66
72
  attr_reader :service, :batch, :publish_thread_pool,
67
- :callback_thread_pool
73
+ :callback_thread_pool, :flow_controller
68
74
 
69
75
  ##
70
76
  # @private Create a new instance of the object.
71
- def initialize topic_name, service, max_bytes: 1_000_000, max_messages: 100, interval: 0.01, threads: {}
77
+ def initialize topic_name,
78
+ service,
79
+ max_bytes: 1_000_000,
80
+ max_messages: 100,
81
+ interval: 0.01,
82
+ threads: {},
83
+ flow_control: {}
72
84
  # init MonitorMixin
73
85
  super()
74
86
  @topic_name = service.topic_path topic_name
@@ -79,6 +91,10 @@ module Google
79
91
  @interval = interval
80
92
  @publish_threads = (threads[:publish] || 2).to_i
81
93
  @callback_threads = (threads[:callback] || 4).to_i
94
+ @flow_control = {
95
+ message_limit: 10 * @max_messages,
96
+ byte_limit: 10 * @max_bytes
97
+ }.merge(flow_control).freeze
82
98
 
83
99
  @published_at = nil
84
100
  @publish_thread_pool = Concurrent::ThreadPoolExecutor.new max_threads: @publish_threads
@@ -87,7 +103,7 @@ module Google
87
103
  @ordered = false
88
104
  @batches = {}
89
105
  @cond = new_cond
90
-
106
+ @flow_controller = FlowController.new(**@flow_control)
91
107
  @thread = Thread.new { run_background }
92
108
  end
93
109
 
@@ -117,13 +133,22 @@ module Google
117
133
  #
118
134
  def publish data = nil, attributes = nil, ordering_key: nil, **extra_attrs, &callback
119
135
  msg = Convert.pubsub_message data, attributes, ordering_key, extra_attrs
136
+ begin
137
+ @flow_controller.acquire msg.to_proto.bytesize
138
+ rescue FlowControlLimitError => e
139
+ stop_publish ordering_key, e if ordering_key
140
+ raise
141
+ end
120
142
 
121
143
  synchronize do
122
144
  raise AsyncPublisherStopped if @stopped
123
145
  raise OrderedMessagesDisabled if !@ordered && !msg.ordering_key.empty? # default is empty string
124
146
 
125
147
  batch = resolve_batch_for_message msg
126
- raise OrderingKeyError, batch.ordering_key if batch.canceled?
148
+ if batch.canceled?
149
+ @flow_controller.release msg.to_proto.bytesize
150
+ raise OrderingKeyError, batch.ordering_key
151
+ end
127
152
  batch_action = batch.add msg, callback
128
153
  if batch_action == :full
129
154
  publish_batches!
@@ -301,9 +326,24 @@ module Google
301
326
  @batches[ordering_key]
302
327
  end
303
328
 
329
+ def stop_publish ordering_key, err
330
+ synchronize do
331
+ batch = resolve_batch_for_ordering_key ordering_key
332
+ return if batch.nil?
333
+ items = batch.cancel!
334
+ items.each do |item|
335
+ @flow_controller.release item.bytesize
336
+ next unless item.callback
337
+
338
+ publish_result = PublishResult.from_error item.msg, err
339
+ execute_callback_async item.callback, publish_result
340
+ end
341
+ end
342
+ end
343
+
304
344
  def publish_batches! stop: nil
305
345
  @batches.reject! { |_ordering_key, batch| batch.empty? }
306
- @batches.values.each do |batch|
346
+ @batches.each_value do |batch|
307
347
  ready = batch.publish! stop: stop
308
348
  publish_batch_async @topic_name, batch if ready
309
349
  end
@@ -321,7 +361,6 @@ module Google
321
361
  end
322
362
 
323
363
  # rubocop:disable Metrics/AbcSize
324
- # rubocop:disable Metrics/MethodLength
325
364
 
326
365
  def publish_batch_sync topic_name, batch
327
366
  # The only batch methods that are safe to call from the loop are
@@ -333,6 +372,7 @@ module Google
333
372
  unless items.empty?
334
373
  grpc = @service.publish topic_name, items.map(&:msg)
335
374
  items.zip Array(grpc.message_ids) do |item, id|
375
+ @flow_controller.release item.bytesize
336
376
  next unless item.callback
337
377
 
338
378
  item.msg.message_id = id
@@ -359,6 +399,7 @@ module Google
359
399
  end
360
400
 
361
401
  items.each do |item|
402
+ @flow_controller.release item.bytesize
362
403
  next unless item.callback
363
404
 
364
405
  publish_result = PublishResult.from_error item.msg, e
@@ -370,7 +411,6 @@ module Google
370
411
  end
371
412
 
372
413
  # rubocop:enable Metrics/AbcSize
373
- # rubocop:enable Metrics/MethodLength
374
414
 
375
415
  PUBLISH_RETRY_ERRORS = [
376
416
  GRPC::Cancelled, GRPC::DeadlineExceeded, GRPC::Internal,
@@ -25,7 +25,8 @@ module Google
25
25
  class Batch
26
26
  include MonitorMixin
27
27
 
28
- attr_reader :items, :ordering_key
28
+ attr_reader :items
29
+ attr_reader :ordering_key
29
30
 
30
31
  def initialize publisher, ordering_key
31
32
  # init MonitorMixin
@@ -128,8 +129,8 @@ module Google
128
129
  end
129
130
 
130
131
  ##
131
- # Rebalances the batch by moving any queued items that will fit into
132
- # the active item list.
132
+ # Fills the batch by sequentially moving the queued items that will
133
+ # fit into the active item list.
133
134
  #
134
135
  # This method is only intended to be used by the active publishing
135
136
  # job.
@@ -151,8 +152,6 @@ module Google
151
152
  end
152
153
  end
153
154
 
154
- # rubocop:disable Metrics/MethodLength
155
-
156
155
  ##
157
156
  # Resets the batch after a successful publish. This clears the active
158
157
  # item list and moves the queued items that will fit into the active
@@ -201,8 +200,6 @@ module Google
201
200
  true
202
201
  end
203
202
 
204
- # rubocop:enable Metrics/MethodLength
205
-
206
203
  ##
207
204
  # Cancel the batch and hault futher batches until resumed. See
208
205
  # {#resume!} and {#canceled?}.
@@ -13,6 +13,8 @@
13
13
  # limitations under the License.
14
14
 
15
15
 
16
+ require "google/cloud/pubsub/convert"
17
+
16
18
  module Google
17
19
  module Cloud
18
20
  module PubSub
@@ -26,11 +28,12 @@ module Google
26
28
  # pubsub = Google::Cloud::PubSub.new
27
29
  #
28
30
  # topic = pubsub.topic "my-topic"
29
- # msgs = topic.publish do |t|
30
- # t.publish "task 1 completed", foo: :bar
31
- # t.publish "task 2 completed", foo: :baz
32
- # t.publish "task 3 completed", foo: :bif
31
+ # msgs = topic.publish do |batch_publisher|
32
+ # batch_publisher.publish "task 1 completed", foo: :bar
33
+ # batch_publisher.publish "task 2 completed", foo: :baz
34
+ # batch_publisher.publish "task 3 completed", foo: :bif
33
35
  # end
36
+ #
34
37
  class BatchPublisher
35
38
  ##
36
39
  # @private The messages to publish
@@ -38,20 +41,40 @@ module Google
38
41
 
39
42
  ##
40
43
  # @private Create a new instance of the object.
41
- def initialize data = nil, attributes = {}
44
+ def initialize data, attributes, ordering_key, extra_attrs
42
45
  @messages = []
43
46
  @mode = :batch
44
47
  return if data.nil?
45
48
  @mode = :single
46
- publish data, attributes
49
+ publish data, attributes, ordering_key: ordering_key, **extra_attrs
47
50
  end
48
51
 
49
52
  ##
50
53
  # Add a message to the batch to be published to the topic.
51
54
  # All messages added to the batch will be published at once.
52
55
  # See {Google::Cloud::PubSub::Topic#publish}
53
- def publish data, attributes = {}
54
- @messages << create_pubsub_message(data, attributes)
56
+ #
57
+ # @param [String, File] data The message payload. This will be converted
58
+ # to bytes encoded as ASCII-8BIT.
59
+ # @param [Hash] attributes Optional attributes for the message.
60
+ # @param [String] ordering_key Identifies related messages for which
61
+ # publish order should be respected.
62
+ #
63
+ # @example Multiple messages can be sent at the same time using a block:
64
+ # require "google/cloud/pubsub"
65
+ #
66
+ # pubsub = Google::Cloud::PubSub.new
67
+ #
68
+ # topic = pubsub.topic "my-topic"
69
+ # msgs = topic.publish do |batch_publisher|
70
+ # batch_publisher.publish "task 1 completed", foo: :bar
71
+ # batch_publisher.publish "task 2 completed", foo: :baz
72
+ # batch_publisher.publish "task 3 completed", foo: :bif
73
+ # end
74
+ #
75
+ def publish data, attributes = nil, ordering_key: nil, **extra_attrs
76
+ msg = Convert.pubsub_message data, attributes, ordering_key, extra_attrs
77
+ @messages << msg
55
78
  end
56
79
 
57
80
  ##
@@ -69,28 +92,6 @@ module Google
69
92
  msgs
70
93
  end
71
94
  end
72
-
73
- protected
74
-
75
- def create_pubsub_message data, attributes
76
- attributes ||= {}
77
- if data.is_a?(::Hash) && attributes.empty?
78
- attributes = data
79
- data = nil
80
- end
81
- # Convert IO-ish objects to strings
82
- if data.respond_to?(:read) && data.respond_to?(:rewind)
83
- data.rewind
84
- data = data.read
85
- end
86
- # Convert data to encoded byte array to match the protobuf defn
87
- data_bytes = String(data).dup.force_encoding(Encoding::ASCII_8BIT).freeze
88
-
89
- # Convert attributes to strings to match the protobuf definition
90
- attributes = Hash[attributes.map { |k, v| [String(k), String(v)] }]
91
-
92
- Google::Cloud::PubSub::V1::PubsubMessage.new data: data_bytes, attributes: attributes
93
- end
94
95
  end
95
96
  end
96
97