google-cloud-pubsub 1.1.3 → 1.2.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: 1feb85392aa3adbb0358718fbd2b3f9cfad766c2dd30fa03ffdd93a0ab9199f3
4
- data.tar.gz: 726f51f0d1851d82de1ee42230da2480a39d1dc18e3ebe418afdb03ce28fa6ea
3
+ metadata.gz: 75209fd682462904d589c3279cfad8bf7fdd1c546646a9f70c3ab419e14072a2
4
+ data.tar.gz: 11145f0b0969362c0ee516e69eb8d800b54f7e51a4f99fdb5febe3c6c3ec69dd
5
5
  SHA512:
6
- metadata.gz: 9c9b2ac59f9fac674bb1bfbddf8d5a23cf768986fbd13e0e41128bf86574884b3d46cd88c564f9b28a531dfebaf6ba05bced34d5f6ee50664442876eea601d6a
7
- data.tar.gz: e3e93f611b142aad3e8323d3aeae2339c810924f31369370e668063da54af64806b0270db81c75b2e6361537ec596d238a5bad4c8cdf79a4d818af08790efc6b
6
+ metadata.gz: 60ed4425c9b18550f4e8fdc849b374aa2dc5c0a6f9425df3e3afbdda85210f0d90d2e3dfde1ba97093c5beb6d22c1db713cd34dcc3a88160719c614ef45f9527
7
+ data.tar.gz: b1c6e793946e32530e5ad017a30951e08b287889e207d32a09e17db5b9d8d6f81cb697eaa42bd9067b707217cf260ab15bff359c6f70a99b5f9f41767600d359
data/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Release History
2
2
 
3
+ ### 1.2.0 / 2020-01-09
4
+
5
+ #### Features
6
+
7
+ * Add Subscriber inventory settings
8
+ * Add the following settings to Subscriber:
9
+ * Subscriber#inventory_limit
10
+ * Subscriber#inventory_bytesize
11
+ * Subscriber#extension
12
+ * Allow Subscription#listen inventory argument to be a hash.
13
+ * Update AsyncPublisher configuration defaults
14
+ * Update AsyncPublisher defaults to the following:
15
+ * max_bytes to 1MB, was 10MB.
16
+ * max_messages to 100, was 1,000.
17
+ * interval to 10 milliseconds, was 250 milliseconds.
18
+ * publish thread count to 2, was 4
19
+ * callback thread count to 4, was 8.
20
+
3
21
  ### 1.1.3 / 2019-12-18
4
22
 
5
23
  #### Bug Fixes
@@ -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,18 +68,17 @@ 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,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
  #
@@ -54,8 +54,6 @@ module Google
54
54
  # been enabled.
55
55
  # @attr_reader [Integer] streams The number of concurrent streams to open
56
56
  # to pull messages from the subscription. Default is 4.
57
- # @attr_reader [Integer] inventory The number of received messages to be
58
- # collected by subscriber. Default is 1,000.
59
57
  # @attr_reader [Integer] callback_threads The number of threads used to
60
58
  # handle the received messages. Default is 8.
61
59
  # @attr_reader [Integer] push_threads The number of threads to handle
@@ -66,19 +64,16 @@ module Google
66
64
  class Subscriber
67
65
  include MonitorMixin
68
66
 
69
- attr_reader :subscription_name, :callback, :deadline, :streams,
70
- :inventory, :message_ordering, :callback_threads,
67
+ attr_reader :subscription_name, :callback, :deadline, :streams, :message_ordering, :callback_threads,
71
68
  :push_threads
72
69
 
73
70
  ##
74
71
  # @private Implementation attributes.
75
- attr_reader :stream_inventory, :stream_pool, :thread_pool, :buffer,
76
- :service
72
+ attr_reader :stream_pool, :thread_pool, :buffer, :service
77
73
 
78
74
  ##
79
75
  # @private Create an empty {Subscriber} object.
80
- def initialize subscription_name, callback, deadline: nil,
81
- message_ordering: nil, streams: nil, inventory: nil,
76
+ def initialize subscription_name, callback, deadline: nil, message_ordering: nil, streams: nil, inventory: nil,
82
77
  threads: {}, service: nil
83
78
  super() # to init MonitorMixin
84
79
 
@@ -86,17 +81,19 @@ module Google
86
81
  @error_callbacks = []
87
82
  @subscription_name = subscription_name
88
83
  @deadline = deadline || 60
89
- @streams = streams || 4
90
- @inventory = inventory || 1000
84
+ @streams = streams || 2
85
+ @inventory = inventory
86
+ @inventory = { limit: @inventory } unless inventory.is_a? Hash
87
+ @inventory[:limit] = Integer(@inventory[:limit] || 1000)
88
+ @inventory[:bytesize] = Integer(@inventory[:bytesize] || 100_000_000)
89
+ @inventory[:extension] = Integer(@inventory[:extension] || 3600)
91
90
  @message_ordering = message_ordering
92
- @callback_threads = (threads[:callback] || 8).to_i
93
- @push_threads = (threads[:push] || 4).to_i
91
+ @callback_threads = Integer(threads[:callback] || 8)
92
+ @push_threads = Integer(threads[:push] || 4)
94
93
 
95
- @stream_inventory = @inventory.fdiv(@streams).ceil
96
94
  @service = service
97
95
 
98
- @started = nil
99
- @stopped = nil
96
+ @started = @stopped = nil
100
97
 
101
98
  stream_pool = Array.new @streams do
102
99
  Thread.new { Stream.new self }
@@ -284,6 +281,36 @@ module Google
284
281
  synchronize { @last_error }
285
282
  end
286
283
 
284
+ ##
285
+ # The number of received messages to be collected by subscriber. Default is 1,000.
286
+ def inventory_limit
287
+ @inventory[:limit]
288
+ end
289
+ # @deprecated Use {#inventory_limit}.
290
+ alias inventory inventory_limit
291
+
292
+ ##
293
+ # The total bytesize of received messages to be collected by subscriber. Default is 100,000,000 (100MB).
294
+ def inventory_bytesize
295
+ @inventory[:bytesize]
296
+ end
297
+
298
+ ##
299
+ # The number of seconds that received messages can be held awaiting processing. Default is 3,600 (1 hour).
300
+ def inventory_extension
301
+ @inventory[:extension]
302
+ end
303
+
304
+ ##
305
+ # @private
306
+ def stream_inventory
307
+ {
308
+ limit: @inventory[:limit].fdiv(@streams).ceil,
309
+ bytesize: @inventory[:bytesize].fdiv(@streams).ceil,
310
+ extension: @inventory[:extension]
311
+ }
312
+ end
313
+
287
314
  # @private returns error object from the stream thread.
288
315
  def error! error
289
316
  error_callbacks = synchronize do
@@ -22,30 +22,39 @@ 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
28
34
 
29
- def initialize stream, limit
35
+ def initialize stream, limit:, bytesize:, extension:
30
36
  super()
31
-
32
37
  @stream = stream
33
38
  @limit = limit
34
- @_ack_ids = []
39
+ @bytesize = bytesize
40
+ @extension = extension
41
+ @inventory = {}
35
42
  @wait_cond = new_cond
36
43
  end
37
44
 
38
45
  def ack_ids
39
- @_ack_ids
46
+ @inventory.keys
40
47
  end
41
48
 
42
- def add *ack_ids
43
- ack_ids.flatten!
44
- ack_ids.compact!
45
- return if ack_ids.empty?
49
+ def add *rec_msgs
50
+ rec_msgs.flatten!
51
+ rec_msgs.compact!
52
+ return if rec_msgs.empty?
46
53
 
47
54
  synchronize do
48
- @_ack_ids += ack_ids
55
+ rec_msgs.each do |rec_msg|
56
+ @inventory[rec_msg.ack_id] = InventoryItem.from rec_msg
57
+ end
49
58
  @wait_cond.broadcast
50
59
  end
51
60
  end
@@ -56,20 +65,34 @@ module Google
56
65
  return if ack_ids.empty?
57
66
 
58
67
  synchronize do
59
- @_ack_ids -= ack_ids
68
+ @inventory.delete_if { |ack_id, _| ack_ids.include? ack_id }
69
+ @wait_cond.broadcast
70
+ end
71
+ end
72
+
73
+ def remove_expired!
74
+ synchronize do
75
+ extension_time = Time.new - extension
76
+ @inventory.delete_if { |_ack_id, item| item.pulled_at < extension_time }
60
77
  @wait_cond.broadcast
61
78
  end
62
79
  end
63
80
 
64
81
  def count
65
82
  synchronize do
66
- @_ack_ids.count
83
+ @inventory.count
84
+ end
85
+ end
86
+
87
+ def total_bytesize
88
+ synchronize do
89
+ @inventory.values.sum(&:bytesize)
67
90
  end
68
91
  end
69
92
 
70
93
  def empty?
71
94
  synchronize do
72
- @_ack_ids.empty?
95
+ @inventory.empty?
73
96
  end
74
97
  end
75
98
 
@@ -93,7 +116,9 @@ module Google
93
116
  end
94
117
 
95
118
  def full?
96
- count >= limit
119
+ synchronize do
120
+ @inventory.count >= limit || @inventory.values.sum(&:bytesize) >= bytesize
121
+ end
97
122
  end
98
123
 
99
124
  protected
@@ -181,8 +181,8 @@ module Google
181
181
  synchronize do
182
182
  return true if @inventory.empty?
183
183
 
184
- @subscriber.buffer.renew_lease @subscriber.deadline,
185
- @inventory.ack_ids
184
+ @inventory.remove_expired!
185
+ @subscriber.buffer.renew_lease @subscriber.deadline, @inventory.ack_ids
186
186
  unpause_streaming!
187
187
  end
188
188
 
@@ -243,17 +243,13 @@ module Google
243
243
  # Cannot syncronize the enumerator, causes deadlock
244
244
  response = enum.next
245
245
 
246
- # Create a list of all the received ack_id values
247
- received_ack_ids = response.received_messages.map(&:ack_id)
248
-
249
246
  # Use synchronize so both changes happen atomically
250
247
  synchronize do
251
248
  # Create receipt of received messages reception
252
- @subscriber.buffer.modify_ack_deadline @subscriber.deadline,
253
- received_ack_ids
249
+ @subscriber.buffer.modify_ack_deadline @subscriber.deadline, response.received_messages.map(&:ack_id)
254
250
 
255
251
  # Add received messages to inventory
256
- @inventory.add received_ack_ids
252
+ @inventory.add response.received_messages
257
253
  end
258
254
 
259
255
  response.received_messages.each do |rec_msg_grpc|
@@ -556,8 +556,16 @@ module Google
556
556
  # argument is not provided. See {#reference?}.
557
557
  # @param [Integer] streams The number of concurrent streams to open to
558
558
  # pull messages from the subscription. Default is 4. Optional.
559
- # @param [Integer] inventory The number of received messages to be
560
- # collected by subscriber. Default is 1,000. Optional.
559
+ # @param [Hash, Integer] inventory The settings to control how received messages are to be handled by the
560
+ # subscriber. When provided as an Integer instead of a Hash only the `limit` will be set. Optional.
561
+ #
562
+ # Hash keys and values may include the following:
563
+ #
564
+ # * `:limit` (Integer) The number of received messages to be collected by subscriber. Default is 1,000.
565
+ # * `:bytesize` (Integer) The total bytesize of received messages to be collected by subscriber. Default is
566
+ # 100,000,000 (100MB).
567
+ # * `:extension` (Integer) The number of seconds that received messages can be held awaiting processing.
568
+ # Default is 3,600 (1 hour).
561
569
  # @param [Hash] threads The number of threads to create to handle
562
570
  # concurrent calls by each stream opened by the subscriber. Optional.
563
571
  #
@@ -16,7 +16,7 @@
16
16
  module Google
17
17
  module Cloud
18
18
  module PubSub
19
- VERSION = "1.1.3".freeze
19
+ VERSION = "1.2.0".freeze
20
20
  end
21
21
 
22
22
  Pubsub = PubSub unless const_defined? :Pubsub
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google-cloud-pubsub
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.3
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Moore
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-12-20 00:00:00.000000000 Z
12
+ date: 2020-01-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: concurrent-ruby