google-cloud-pubsub 1.1.3 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +122 -0
  3. data/EMULATOR.md +1 -1
  4. data/TROUBLESHOOTING.md +2 -8
  5. data/lib/google/cloud/pubsub/async_publisher.rb +15 -19
  6. data/lib/google/cloud/pubsub/project.rb +18 -26
  7. data/lib/google/cloud/pubsub/received_message.rb +38 -0
  8. data/lib/google/cloud/pubsub/retry_policy.rb +90 -0
  9. data/lib/google/cloud/pubsub/service.rb +37 -15
  10. data/lib/google/cloud/pubsub/subscriber/inventory.rb +43 -15
  11. data/lib/google/cloud/pubsub/subscriber/stream.rb +7 -8
  12. data/lib/google/cloud/pubsub/subscriber.rb +86 -15
  13. data/lib/google/cloud/pubsub/subscription/push_config.rb +2 -2
  14. data/lib/google/cloud/pubsub/subscription.rb +296 -6
  15. data/lib/google/cloud/pubsub/topic.rb +65 -2
  16. data/lib/google/cloud/pubsub/v1/credentials.rb +1 -1
  17. data/lib/google/cloud/pubsub/v1/doc/google/iam/v1/iam_policy.rb +1 -1
  18. data/lib/google/cloud/pubsub/v1/doc/google/iam/v1/options.rb +1 -1
  19. data/lib/google/cloud/pubsub/v1/doc/google/iam/v1/policy.rb +1 -1
  20. data/lib/google/cloud/pubsub/v1/doc/google/protobuf/duration.rb +1 -1
  21. data/lib/google/cloud/pubsub/v1/doc/google/protobuf/empty.rb +1 -1
  22. data/lib/google/cloud/pubsub/v1/doc/google/protobuf/field_mask.rb +1 -1
  23. data/lib/google/cloud/pubsub/v1/doc/google/protobuf/timestamp.rb +1 -1
  24. data/lib/google/cloud/pubsub/v1/doc/google/pubsub/v1/pubsub.rb +168 -79
  25. data/lib/google/cloud/pubsub/v1/doc/google/type/expr.rb +1 -1
  26. data/lib/google/cloud/pubsub/v1/publisher_client.rb +175 -33
  27. data/lib/google/cloud/pubsub/v1/publisher_client_config.json +16 -1
  28. data/lib/google/cloud/pubsub/v1/subscriber_client.rb +145 -64
  29. data/lib/google/cloud/pubsub/v1/subscriber_client_config.json +12 -3
  30. data/lib/google/cloud/pubsub/version.rb +1 -1
  31. data/lib/google/pubsub/v1/pubsub_pb.rb +20 -0
  32. data/lib/google/pubsub/v1/pubsub_services_pb.rb +7 -3
  33. metadata +6 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1feb85392aa3adbb0358718fbd2b3f9cfad766c2dd30fa03ffdd93a0ab9199f3
4
- data.tar.gz: 726f51f0d1851d82de1ee42230da2480a39d1dc18e3ebe418afdb03ce28fa6ea
3
+ metadata.gz: 43ee60087a74bfc9938a61cf66f67b937f30c440f921ef83294f5dd2ec8e1079
4
+ data.tar.gz: 9104bacc161434e7edc1b5553cb0d2f2681ddd6a6a000bf947e212af7dad4df0
5
5
  SHA512:
6
- metadata.gz: 9c9b2ac59f9fac674bb1bfbddf8d5a23cf768986fbd13e0e41128bf86574884b3d46cd88c564f9b28a531dfebaf6ba05bced34d5f6ee50664442876eea601d6a
7
- data.tar.gz: e3e93f611b142aad3e8323d3aeae2339c810924f31369370e668063da54af64806b0270db81c75b2e6361537ec596d238a5bad4c8cdf79a4d818af08790efc6b
6
+ metadata.gz: 4130c4d2961f54b8cf6f1a5957f50d50e37d57bcd56d032df3bbc10497e8788d55e405c69b8570cc24322800af37a35e49daf67755b1652b763b5a9da44b464e
7
+ data.tar.gz: 5777e0c8d1ca9d56c2a94056971b1e59ccf63e3a1e6dd532f5d223f7a6b8a80f0f0aa29bf1aa984376b48d279bccc3e23aa4ff50940c47b4920c47a6340e5975
data/CHANGELOG.md CHANGED
@@ -1,5 +1,127 @@
1
1
  # Release History
2
2
 
3
+ ### 1.10.0 / 2020-07-23
4
+
5
+ #### Features
6
+
7
+ * Add Subscription#detach and #detached?
8
+
9
+ ### 1.9.0 / 2020-07-21
10
+
11
+ #### Features
12
+
13
+ * Add support for server-side flow control
14
+
15
+ ### 1.8.0 / 2020-06-29
16
+
17
+ #### Features
18
+
19
+ * Add Subscription#filter
20
+
21
+ ### 1.7.1 / 2020-05-28
22
+
23
+ #### Documentation
24
+
25
+ * Fix a few broken links
26
+
27
+ ### 1.7.0 / 2020-05-21
28
+
29
+ #### Features
30
+
31
+ * Add Retry Policy support
32
+ * Add RetryPolicy
33
+ * Add retry_policy param to Topic#subscribe
34
+ * Add Subscription#retry_policy
35
+ * Add Subscription#retry_policy=
36
+ * Set client-scoped UUID in initial StreamingPullRequest#client_id
37
+
38
+ ### 1.6.1 / 2020-05-06
39
+
40
+ #### Documentation
41
+
42
+ * Fix example in Emulator documentation
43
+ * Remove experimental notice from ReceivedMessage#delivery_attempt
44
+ * Wrap example URLs in backticks
45
+
46
+ ### 1.6.0 / 2020-04-06
47
+
48
+ #### Features
49
+
50
+ * Add list_topic_snapshots and get_snapshot
51
+ * Add PublisherClient#list_topic_snapshots
52
+ * Add SubscriberClient#get_snapshot
53
+
54
+ #### Documentation
55
+
56
+ * Remove a spurious link in the low-level interface documentation.
57
+
58
+ ### 1.5.0 / 2020-03-25
59
+
60
+ #### Features
61
+
62
+ * Add max_duration_per_lease_extension to Subscription#listen and Subscriber
63
+
64
+ ### 1.4.0 / 2020-03-11
65
+
66
+ #### Features
67
+
68
+ * Rename Subscriber inventory methods and params
69
+ * Rename Subscriber#inventory_limit to #max_outstanding_messages
70
+ * Rename Subscriber#bytesize to #max_outstanding_bytes
71
+ * Rename Subscriber#extension to #max_total_lease_duration
72
+ * Add deprecated aliases for the original methods
73
+ * Support separate project setting for quota/billing
74
+
75
+ #### Documentation
76
+
77
+ * Update documentation in the lower-level client
78
+
79
+ ### 1.3.1 / 2020-02-18
80
+
81
+ #### Bug Fixes
82
+
83
+ * Move Thread.new to end of AsyncPublisher#initialize
84
+
85
+ ### 1.3.0 / 2020-02-10
86
+
87
+ #### Features
88
+
89
+ * Add support for Dead Letter Topics
90
+ * Add `dead_letter_topic` and `dead_letter_max_delivery_attempts` to `Topic#subscribe`
91
+ * Add `Subscription#dead_letter_topic` and `Subscription#dead_letter_topic=`
92
+ * Add `Subscription#dead_letter_max_delivery_attempts` and `Subscription#dead_letter_max_delivery_attempts=`
93
+ * Add `ReceivedMessage#delivery_attempt`
94
+
95
+ ### 1.2.2 / 2020-02-04
96
+
97
+ #### Performance Improvements
98
+
99
+ * Add StreamingPullRequest#client_id to the lower-level API
100
+
101
+ ### 1.2.1 / 2020-01-23
102
+
103
+ #### Documentation
104
+
105
+ * Update copyright year
106
+
107
+ ### 1.2.0 / 2020-01-09
108
+
109
+ #### Features
110
+
111
+ * Add Subscriber inventory settings
112
+ * Add the following settings to Subscriber:
113
+ * Subscriber#inventory_limit
114
+ * Subscriber#inventory_bytesize
115
+ * Subscriber#extension
116
+ * Allow Subscription#listen inventory argument to be a hash.
117
+ * Update AsyncPublisher configuration defaults
118
+ * Update AsyncPublisher defaults to the following:
119
+ * max_bytes to 1MB, was 10MB.
120
+ * max_messages to 100, was 1,000.
121
+ * interval to 10 milliseconds, was 250 milliseconds.
122
+ * publish thread count to 2, was 4
123
+ * callback thread count to 4, was 8.
124
+
3
125
  ### 1.1.3 / 2019-12-18
4
126
 
5
127
  #### Bug Fixes
data/EMULATOR.md CHANGED
@@ -17,7 +17,7 @@ require "google/cloud/pubsub"
17
17
  # Make Pub/Sub use the emulator
18
18
  ENV["PUBSUB_EMULATOR_HOST"] = "localhost:8918"
19
19
 
20
- pubsub = Google::Cloud::PubSub.new "emulator-project-id"
20
+ pubsub = Google::Cloud::PubSub.new project_id:"emulator-project-id"
21
21
 
22
22
  # Get a topic in the current project
23
23
  my_topic = pubsub.new_topic "my-topic"
data/TROUBLESHOOTING.md CHANGED
@@ -24,14 +24,8 @@ improved, *please* create a new issue on GitHub so we can talk about it.
24
24
 
25
25
  - [New issue][gh-ruby]
26
26
 
27
- Or, you can ask questions on the [Google Cloud Platform Slack][slack-ruby]. You
28
- can use the "ruby" channel for general Ruby questions, or use the
29
- "google-cloud-ruby" channel if you have questions about this gem in particular.
30
-
31
27
  [so-ruby]: http://stackoverflow.com/questions/tagged/google-cloud-platform+ruby+pubsub
32
28
 
33
- [gh-search-ruby]: https://github.com/googlecloudplatform/google-cloud-ruby/issues?q=label%3A%22api%3A+pubsub%22
34
-
35
- [gh-ruby]: https://github.com/googlecloudplatform/google-cloud-ruby/issues/new
29
+ [gh-search-ruby]: https://github.com/googleapis/google-cloud-ruby/issues?q=label%3A%22api%3A+pubsub%22
36
30
 
37
- [slack-ruby]: https://gcp-slack.appspot.com/
31
+ [gh-ruby]: https://github.com/googleapis/google-cloud-ruby/issues/new
@@ -44,20 +44,17 @@ module Google
44
44
  #
45
45
  # topic.async_publisher.stop.wait!
46
46
  #
47
- # @attr_reader [String] topic_name The name of the topic the messages
48
- # are published to. In the form of
47
+ # @attr_reader [String] topic_name The name of the topic the messages are published to. In the form of
49
48
  # "/projects/project-identifier/topics/topic-name".
50
- # @attr_reader [Integer] max_bytes The maximum size of messages to be
51
- # collected before the batch is published. Default is 10,000,000
52
- # (10MB).
53
- # @attr_reader [Integer] max_messages The maximum number of messages to
54
- # be collected before the batch is published. Default is 1,000.
55
- # @attr_reader [Numeric] interval The number of seconds to collect
56
- # messages before the batch is published. Default is 0.25.
57
- # @attr_reader [Numeric] publish_threads The number of threads used to
58
- # publish messages. Default is 4.
59
- # @attr_reader [Numeric] callback_threads The number of threads to
60
- # handle the published messages' callbacks. Default is 8.
49
+ # @attr_reader [Integer] max_bytes The maximum size of messages to be collected before the batch is published.
50
+ # Default is 1,000,000 (1MB).
51
+ # @attr_reader [Integer] max_messages The maximum number of messages to be collected before the batch is
52
+ # published. Default is 100.
53
+ # @attr_reader [Numeric] interval The number of seconds to collect messages before the batch is published. Default
54
+ # is 0.01.
55
+ # @attr_reader [Numeric] publish_threads The number of threads used to publish messages. Default is 2.
56
+ # @attr_reader [Numeric] callback_threads The number of threads to handle the published messages' callbacks.
57
+ # Default is 4.
61
58
  #
62
59
  class AsyncPublisher
63
60
  include MonitorMixin
@@ -71,28 +68,27 @@ module Google
71
68
 
72
69
  ##
73
70
  # @private Create a new instance of the object.
74
- def initialize topic_name, service, max_bytes: 10_000_000, max_messages: 1000, interval: 0.25, threads: {}
71
+ def initialize topic_name, service, max_bytes: 1_000_000, max_messages: 100, interval: 0.01, threads: {}
75
72
  # init MonitorMixin
76
73
  super()
77
-
78
74
  @topic_name = service.topic_path topic_name
79
75
  @service = service
80
76
 
81
77
  @max_bytes = max_bytes
82
78
  @max_messages = max_messages
83
79
  @interval = interval
84
- @publish_threads = (threads[:publish] || 4).to_i
85
- @callback_threads = (threads[:callback] || 8).to_i
80
+ @publish_threads = (threads[:publish] || 2).to_i
81
+ @callback_threads = (threads[:callback] || 4).to_i
86
82
 
87
83
  @published_at = nil
88
84
  @publish_thread_pool = Concurrent::ThreadPoolExecutor.new max_threads: @publish_threads
89
85
  @callback_thread_pool = Concurrent::ThreadPoolExecutor.new max_threads: @callback_threads
90
- @thread = Thread.new { run_background }
91
86
 
92
87
  @ordered = false
93
88
  @batches = {}
94
-
95
89
  @cond = new_cond
90
+
91
+ @thread = Thread.new { run_background }
96
92
  end
97
93
 
98
94
  ##
@@ -89,19 +89,15 @@ module Google
89
89
  #
90
90
  # Hash keys and values may include the following:
91
91
  #
92
- # * `:max_bytes` (Integer) The maximum size of messages to be
93
- # collected before the batch is published. Default is 10,000,000
94
- # (10MB).
95
- # * `:max_messages` (Integer) The maximum number of messages to be
96
- # collected before the batch is published. Default is 1,000.
97
- # * `:interval` (Numeric) The number of seconds to collect messages
98
- # before the batch is published. Default is 0.25.
99
- # * `:threads` (Hash) The number of threads to create to handle
100
- # concurrent calls by the publisher:
101
- # * `:publish` (Integer) The number of threads used to publish
102
- # messages. Default is 4.
103
- # * `:callback` (Integer) The number of threads to handle the
104
- # published messages' callbacks. Default is 8.
92
+ # * `:max_bytes` (Integer) The maximum size of messages to be collected before the batch is published. Default
93
+ # is 1,000,000 (1MB).
94
+ # * `:max_messages` (Integer) The maximum number of messages to be collected before the batch is published.
95
+ # Default is 100.
96
+ # * `:interval` (Numeric) The number of seconds to collect messages before the batch is published. Default is
97
+ # 0.01.
98
+ # * `:threads` (Hash) The number of threads to create to handle concurrent calls by the publisher:
99
+ # * `:publish` (Integer) The number of threads used to publish messages. Default is 2.
100
+ # * `:callback` (Integer) The number of threads to handle the published messages' callbacks. Default is 4.
105
101
  #
106
102
  # @return [Google::Cloud::PubSub::Topic, nil] Returns `nil` if topic
107
103
  # does not exist.
@@ -183,19 +179,15 @@ module Google
183
179
  #
184
180
  # Hash keys and values may include the following:
185
181
  #
186
- # * `:max_bytes` (Integer) The maximum size of messages to be
187
- # collected before the batch is published. Default is 10,000,000
188
- # (10MB).
189
- # * `:max_messages` (Integer) The maximum number of messages to be
190
- # collected before the batch is published. Default is 1,000.
191
- # * `:interval` (Numeric) The number of seconds to collect messages
192
- # before the batch is published. Default is 0.25.
193
- # * `:threads` (Hash) The number of threads to create to handle
194
- # concurrent calls by the publisher:
195
- # * `:publish` (Integer) The number of threads used to publish
196
- # messages. Default is 4.
197
- # * `:callback` (Integer) The number of threads to handle the
198
- # published messages' callbacks. Default is 8.
182
+ # * `:max_bytes` (Integer) The maximum size of messages to be collected before the batch is published. Default
183
+ # is 1,000,000 (1MB).
184
+ # * `:max_messages` (Integer) The maximum number of messages to be collected before the batch is published.
185
+ # Default is 100.
186
+ # * `:interval` (Numeric) The number of seconds to collect messages before the batch is published. Default is
187
+ # 0.01.
188
+ # * `:threads` (Hash) The number of threads to create to handle concurrent calls by the publisher:
189
+ # * `:publish` (Integer) The number of threads used to publish messages. Default is 2.
190
+ # * `:callback` (Integer) The number of threads to handle the published messages' callbacks. Default is 4.
199
191
  #
200
192
  # @return [Google::Cloud::PubSub::Topic]
201
193
  #
@@ -63,6 +63,44 @@ module Google
63
63
  @grpc.ack_id
64
64
  end
65
65
 
66
+ ##
67
+ # Returns the delivery attempt counter for the message. If a dead letter policy is not set on the subscription,
68
+ # this will be `nil`. See {Topic#subscribe}, {Subscription#dead_letter_topic=} and
69
+ # {Subscription#dead_letter_max_delivery_attempts=}.
70
+ #
71
+ # The delivery attempt counter is `1 + (the sum of number of NACKs and number of ack_deadline exceeds)` for the
72
+ # message.
73
+ #
74
+ # A NACK is any call to `ModifyAckDeadline` with a `0` deadline. An `ack_deadline` exceeds event is whenever a
75
+ # message is not acknowledged within `ack_deadline`. Note that `ack_deadline` is initially
76
+ # `Subscription.ackDeadlineSeconds`, but may get extended automatically by the client library.
77
+ #
78
+ # The first delivery of a given message will have this value as `1`. The value is calculated at best effort and
79
+ # is approximate.
80
+ #
81
+ # @return [Integer, nil] A delivery attempt value of `1` or greater, or `nil` if a dead letter policy is not set
82
+ # on the subscription.
83
+ #
84
+ # @example
85
+ # require "google/cloud/pubsub"
86
+ #
87
+ # pubsub = Google::Cloud::PubSub.new
88
+ #
89
+ # topic = pubsub.topic "my-topic"
90
+ # dead_letter_topic = pubsub.topic "my-dead-letter-topic", skip_lookup: true
91
+ # sub = topic.subscribe "my-topic-sub",
92
+ # dead_letter_topic: dead_letter_topic,
93
+ # dead_letter_max_delivery_attempts: 10
94
+ #
95
+ # subscriber = sub.listen do |received_message|
96
+ # puts received_message.message.delivery_attempt
97
+ # end
98
+ #
99
+ def delivery_attempt
100
+ return nil if @grpc.delivery_attempt && @grpc.delivery_attempt < 1
101
+ @grpc.delivery_attempt
102
+ end
103
+
66
104
  ##
67
105
  # The received message.
68
106
  def message
@@ -0,0 +1,90 @@
1
+ # Copyright 2016 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ require "google/cloud/errors"
17
+
18
+ module Google
19
+ module Cloud
20
+ module PubSub
21
+ ##
22
+ # # RetryPolicy
23
+ #
24
+ # An immutable Retry Policy value object that specifies how Cloud Pub/Sub retries message delivery.
25
+ #
26
+ # Retry delay will be exponential based on provided minimum and maximum backoffs. (See [Exponential
27
+ # backoff](https://en.wikipedia.org/wiki/Exponential_backoff).)
28
+ #
29
+ # Retry Policy will be triggered on NACKs or acknowledgement deadline exceeded events for a given message.
30
+ #
31
+ # Retry Policy is implemented on a best effort basis. At times, the delay between consecutive deliveries may not
32
+ # match the configuration. That is, delay can be more or less than configured backoff.
33
+ #
34
+ # **EXPERIMENTAL:** This API might be changed in backward-incompatible ways and is not recommended for production
35
+ # use. It is not subject to any SLA or deprecation policy.
36
+ #
37
+ # @attr [Numeric] minimum_backoff The minimum delay between consecutive deliveries of a given message. Value
38
+ # should be between 0 and 600 seconds. The default value is 10 seconds.
39
+ # @attr [Numeric] maximum_backoff The maximum delay between consecutive deliveries of a given message. Value
40
+ # should be between 0 and 600 seconds. The default value is 600 seconds.
41
+ #
42
+ # @example
43
+ # require "google/cloud/pubsub"
44
+ #
45
+ # pubsub = Google::Cloud::PubSub.new
46
+ #
47
+ # sub = pubsub.subscription "my-topic-sub"
48
+ #
49
+ # sub.retry_policy = Google::Cloud::PubSub::RetryPolicy.new minimum_backoff: 5, maximum_backoff: 300
50
+ #
51
+ # sub.retry_policy.minimum_backoff #=> 5
52
+ # sub.retry_policy.maximum_backoff #=> 300
53
+ #
54
+ class RetryPolicy
55
+ attr_reader :minimum_backoff, :maximum_backoff
56
+
57
+ ##
58
+ # Creates a new, immutable RetryPolicy value object.
59
+ #
60
+ # @attr [Numeric, nil] minimum_backoff The minimum delay between consecutive deliveries of a given message.
61
+ # Value should be between 0 and 600 seconds. If `nil` is provided, the default value is 10 seconds.
62
+ # @attr [Numeric, nil] maximum_backoff The maximum delay between consecutive deliveries of a given message.
63
+ # Value should be between 0 and 600 seconds. If `nil` is provided, the default value is 600 seconds.
64
+ #
65
+ def initialize minimum_backoff: nil, maximum_backoff: nil
66
+ @minimum_backoff = minimum_backoff
67
+ @maximum_backoff = maximum_backoff
68
+ end
69
+
70
+ ##
71
+ # @private Convert the RetryPolicy to a Google::Cloud::PubSub::V1::RetryPolicy object.
72
+ def to_grpc
73
+ Google::Cloud::PubSub::V1::RetryPolicy.new(
74
+ minimum_backoff: Convert.number_to_duration(minimum_backoff),
75
+ maximum_backoff: Convert.number_to_duration(maximum_backoff)
76
+ )
77
+ end
78
+
79
+ ##
80
+ # @private New RetryPolicy from a Google::Cloud::PubSub::V1::RetryPolicy object.
81
+ def self.from_grpc grpc
82
+ new(
83
+ minimum_backoff: Convert.duration_to_number(grpc.minimum_backoff),
84
+ maximum_backoff: Convert.duration_to_number(grpc.maximum_backoff)
85
+ )
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -19,6 +19,7 @@ require "google/cloud/pubsub/convert"
19
19
  require "google/cloud/pubsub/version"
20
20
  require "google/cloud/pubsub/v1"
21
21
  require "google/gax/errors"
22
+ require "securerandom"
22
23
 
23
24
  module Google
24
25
  module Cloud
@@ -28,6 +29,12 @@ module Google
28
29
  # methods.
29
30
  class Service
30
31
  attr_accessor :project, :credentials, :host, :timeout, :client_config
32
+ ###
33
+ # The same client_id is used across all streaming pull connections that are created by this client. This is
34
+ # intentional, as it indicates to the server that any guarantees, such as message ordering, made for a stream
35
+ # that is disconnected will be made for the stream that is created to replace it. The attr_accessor allows the
36
+ # value to be replaced for unit testing.
37
+ attr_accessor :client_id
31
38
 
32
39
  ##
33
40
  # Creates a new Service instance.
@@ -38,6 +45,7 @@ module Google
38
45
  @host = host || V1::PublisherClient::SERVICE_ADDRESS
39
46
  @timeout = timeout
40
47
  @client_config = client_config || {}
48
+ @client_id = SecureRandom.uuid.freeze
41
49
  end
42
50
 
43
51
  def channel
@@ -233,21 +241,18 @@ module Google
233
241
  push_endpoint: options[:endpoint],
234
242
  attributes: (options[:attributes] || {}).to_h
235
243
  end
236
- deadline = options[:deadline]
237
- retain_acked = options[:retain_acked]
238
- mrd = Convert.number_to_duration options[:retention]
239
- labels = options[:labels]
240
- message_ordering = options[:message_ordering]
241
-
242
244
  execute do
243
245
  subscriber.create_subscription \
244
246
  name, topic,
245
247
  push_config: push_config,
246
- ack_deadline_seconds: deadline,
247
- retain_acked_messages: retain_acked,
248
- message_retention_duration: mrd,
249
- labels: labels,
250
- enable_message_ordering: message_ordering,
248
+ ack_deadline_seconds: options[:deadline],
249
+ retain_acked_messages: options[:retain_acked],
250
+ message_retention_duration: Convert.number_to_duration(options[:retention]),
251
+ labels: options[:labels],
252
+ enable_message_ordering: options[:message_ordering],
253
+ filter: options[:filter],
254
+ dead_letter_policy: dead_letter_policy(options),
255
+ retry_policy: options[:retry_policy],
251
256
  options: default_options
252
257
  end
253
258
  end
@@ -260,12 +265,20 @@ module Google
260
265
  end
261
266
 
262
267
  ##
263
- # Deletes an existing subscription.
264
- # All pending messages in the subscription are immediately dropped.
268
+ # Deletes an existing subscription. All pending messages in the subscription are immediately dropped.
265
269
  def delete_subscription subscription
266
270
  execute do
267
- subscriber.delete_subscription subscription_path(subscription),
268
- options: default_options
271
+ subscriber.delete_subscription subscription_path(subscription), options: default_options
272
+ end
273
+ end
274
+
275
+ ##
276
+ # Detaches a subscription from its topic. All messages retained in the subscription are dropped. Subsequent
277
+ # `Pull` and `StreamingPull` requests will raise `FAILED_PRECONDITION`. If the subscription is a push
278
+ # subscription, pushes to the endpoint will stop.
279
+ def detach_subscription subscription
280
+ execute do
281
+ publisher.detach_subscription subscription_path(subscription), options: default_options
269
282
  end
270
283
  end
271
284
 
@@ -477,6 +490,15 @@ module Google
477
490
  true
478
491
  end
479
492
 
493
+ def dead_letter_policy options
494
+ return nil unless options[:dead_letter_topic_name]
495
+ policy = Google::Cloud::PubSub::V1::DeadLetterPolicy.new dead_letter_topic: options[:dead_letter_topic_name]
496
+ if options[:dead_letter_max_delivery_attempts]
497
+ policy.max_delivery_attempts = options[:dead_letter_max_delivery_attempts]
498
+ end
499
+ policy
500
+ end
501
+
480
502
  def default_headers
481
503
  { "google-cloud-resource-prefix" => "projects/#{@project}" }
482
504
  end
@@ -22,30 +22,40 @@ module Google
22
22
  ##
23
23
  # @private
24
24
  class Inventory
25
+ InventoryItem = Struct.new :bytesize, :pulled_at do
26
+ def self.from rec_msg
27
+ new rec_msg.to_proto.bytesize, Time.now
28
+ end
29
+ end
30
+
25
31
  include MonitorMixin
26
32
 
27
- attr_reader :stream, :limit
33
+ attr_reader :stream, :limit, :bytesize, :extension, :max_duration_per_lease_extension
28
34
 
29
- def initialize stream, limit
35
+ def initialize stream, limit:, bytesize:, extension:, max_duration_per_lease_extension:
30
36
  super()
31
-
32
37
  @stream = stream
33
38
  @limit = limit
34
- @_ack_ids = []
39
+ @bytesize = bytesize
40
+ @extension = extension
41
+ @max_duration_per_lease_extension = max_duration_per_lease_extension
42
+ @inventory = {}
35
43
  @wait_cond = new_cond
36
44
  end
37
45
 
38
46
  def ack_ids
39
- @_ack_ids
47
+ @inventory.keys
40
48
  end
41
49
 
42
- def add *ack_ids
43
- ack_ids.flatten!
44
- ack_ids.compact!
45
- return if ack_ids.empty?
50
+ def add *rec_msgs
51
+ rec_msgs.flatten!
52
+ rec_msgs.compact!
53
+ return if rec_msgs.empty?
46
54
 
47
55
  synchronize do
48
- @_ack_ids += ack_ids
56
+ rec_msgs.each do |rec_msg|
57
+ @inventory[rec_msg.ack_id] = InventoryItem.from rec_msg
58
+ end
49
59
  @wait_cond.broadcast
50
60
  end
51
61
  end
@@ -56,20 +66,34 @@ module Google
56
66
  return if ack_ids.empty?
57
67
 
58
68
  synchronize do
59
- @_ack_ids -= ack_ids
69
+ @inventory.delete_if { |ack_id, _| ack_ids.include? ack_id }
70
+ @wait_cond.broadcast
71
+ end
72
+ end
73
+
74
+ def remove_expired!
75
+ synchronize do
76
+ extension_time = Time.new - extension
77
+ @inventory.delete_if { |_ack_id, item| item.pulled_at < extension_time }
60
78
  @wait_cond.broadcast
61
79
  end
62
80
  end
63
81
 
64
82
  def count
65
83
  synchronize do
66
- @_ack_ids.count
84
+ @inventory.count
85
+ end
86
+ end
87
+
88
+ def total_bytesize
89
+ synchronize do
90
+ @inventory.values.sum(&:bytesize)
67
91
  end
68
92
  end
69
93
 
70
94
  def empty?
71
95
  synchronize do
72
- @_ack_ids.empty?
96
+ @inventory.empty?
73
97
  end
74
98
  end
75
99
 
@@ -93,7 +117,9 @@ module Google
93
117
  end
94
118
 
95
119
  def full?
96
- count >= limit
120
+ synchronize do
121
+ @inventory.count >= limit || @inventory.values.sum(&:bytesize) >= bytesize
122
+ end
97
123
  end
98
124
 
99
125
  protected
@@ -127,7 +153,9 @@ module Google
127
153
  end
128
154
 
129
155
  def calc_delay
130
- (stream.subscriber.deadline - 3) * rand(0.8..0.9)
156
+ delay = (stream.subscriber.deadline - 3) * rand(0.8..0.9)
157
+ delay = [delay, max_duration_per_lease_extension].min if max_duration_per_lease_extension.positive?
158
+ delay
131
159
  end
132
160
  end
133
161
  end