google-cloud-pubsub 0.20.0 → 2.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.yardopts +18 -0
- data/AUTHENTICATION.md +178 -0
- data/CHANGELOG.md +659 -0
- data/CODE_OF_CONDUCT.md +40 -0
- data/CONTRIBUTING.md +187 -0
- data/EMULATOR.md +37 -0
- data/LICENSE +201 -0
- data/LOGGING.md +32 -0
- data/OVERVIEW.md +528 -0
- data/TROUBLESHOOTING.md +31 -0
- data/lib/google/cloud/pubsub/async_publisher/batch.rb +310 -0
- data/lib/google/cloud/pubsub/async_publisher.rb +402 -0
- data/lib/google/cloud/pubsub/batch_publisher.rb +100 -0
- data/lib/google/cloud/pubsub/convert.rb +91 -0
- data/lib/google/cloud/pubsub/credentials.rb +26 -10
- data/lib/google/cloud/pubsub/errors.rb +85 -0
- data/lib/google/cloud/pubsub/message.rb +82 -20
- data/lib/google/cloud/pubsub/policy.rb +40 -61
- data/lib/google/cloud/pubsub/project.rb +405 -265
- data/lib/google/cloud/pubsub/publish_result.rb +103 -0
- data/lib/google/cloud/pubsub/received_message.rb +165 -30
- data/lib/google/cloud/pubsub/retry_policy.rb +88 -0
- data/lib/google/cloud/pubsub/schema/list.rb +180 -0
- data/lib/google/cloud/pubsub/schema.rb +310 -0
- data/lib/google/cloud/pubsub/service.rb +304 -162
- data/lib/google/cloud/pubsub/snapshot/list.rb +178 -0
- data/lib/google/cloud/pubsub/snapshot.rb +205 -0
- data/lib/google/cloud/pubsub/subscriber/enumerator_queue.rb +54 -0
- data/lib/google/cloud/pubsub/subscriber/inventory.rb +173 -0
- data/lib/google/cloud/pubsub/subscriber/sequencer.rb +115 -0
- data/lib/google/cloud/pubsub/subscriber/stream.rb +400 -0
- data/lib/google/cloud/pubsub/subscriber/timed_unary_buffer.rb +230 -0
- data/lib/google/cloud/pubsub/subscriber.rb +417 -0
- data/lib/google/cloud/pubsub/subscription/list.rb +38 -43
- data/lib/google/cloud/pubsub/subscription/push_config.rb +268 -0
- data/lib/google/cloud/pubsub/subscription.rb +1040 -210
- data/lib/google/cloud/pubsub/topic/list.rb +32 -37
- data/lib/google/cloud/pubsub/topic.rb +726 -177
- data/lib/google/cloud/pubsub/version.rb +6 -4
- data/lib/google/cloud/pubsub.rb +138 -413
- data/lib/google-cloud-pubsub.rb +60 -42
- metadata +88 -39
- data/lib/google/cloud/pubsub/topic/publisher.rb +0 -87
- data/lib/google/iam/v1/iam_policy.rb +0 -33
- data/lib/google/iam/v1/iam_policy_services.rb +0 -30
- data/lib/google/iam/v1/policy.rb +0 -25
- data/lib/google/pubsub/v1/pubsub_pb.rb +0 -129
- data/lib/google/pubsub/v1/pubsub_services_pb.rb +0 -117
@@ -0,0 +1,178 @@
|
|
1
|
+
# Copyright 2017 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 "delegate"
|
17
|
+
|
18
|
+
module Google
|
19
|
+
module Cloud
|
20
|
+
module PubSub
|
21
|
+
class Snapshot
|
22
|
+
##
|
23
|
+
# Snapshot::List is a special case Array with additional values.
|
24
|
+
class List < DelegateClass(::Array)
|
25
|
+
##
|
26
|
+
# If not empty, indicates that there are more snapshots
|
27
|
+
# that match the request and this value should be passed to
|
28
|
+
# the next {Google::Cloud::PubSub::Project#snapshots} to continue.
|
29
|
+
attr_accessor :token
|
30
|
+
|
31
|
+
##
|
32
|
+
# @private Create a new Snapshot::List with an array of values.
|
33
|
+
def initialize arr = []
|
34
|
+
@prefix = nil
|
35
|
+
@token = nil
|
36
|
+
@max = nil
|
37
|
+
super arr
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Whether there a next page of snapshots.
|
42
|
+
#
|
43
|
+
# @return [Boolean]
|
44
|
+
#
|
45
|
+
# @example
|
46
|
+
# require "google/cloud/pubsub"
|
47
|
+
#
|
48
|
+
# pubsub = Google::Cloud::PubSub.new
|
49
|
+
#
|
50
|
+
# snapshots = pubsub.snapshots
|
51
|
+
# if snapshots.next?
|
52
|
+
# next_snapshots = snapshots.next
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
def next?
|
56
|
+
!token.nil?
|
57
|
+
end
|
58
|
+
|
59
|
+
##
|
60
|
+
# Retrieve the next page of snapshots.
|
61
|
+
#
|
62
|
+
# @return [Snapshot::List]
|
63
|
+
#
|
64
|
+
# @example
|
65
|
+
# require "google/cloud/pubsub"
|
66
|
+
#
|
67
|
+
# pubsub = Google::Cloud::PubSub.new
|
68
|
+
#
|
69
|
+
# snapshots = pubsub.snapshots
|
70
|
+
# if snapshots.next?
|
71
|
+
# next_snapshots = snapshots.next
|
72
|
+
# end
|
73
|
+
#
|
74
|
+
def next
|
75
|
+
return nil unless next?
|
76
|
+
ensure_service!
|
77
|
+
next_snapshots
|
78
|
+
end
|
79
|
+
|
80
|
+
##
|
81
|
+
# Retrieves remaining results by repeatedly invoking {#next} until
|
82
|
+
# {#next?} returns `false`. Calls the given block once for each
|
83
|
+
# result, which is passed as the argument to the block.
|
84
|
+
#
|
85
|
+
# An Enumerator is returned if no block is given.
|
86
|
+
#
|
87
|
+
# This method will make repeated API calls until all remaining results
|
88
|
+
# are retrieved. (Unlike `#each`, for example, which merely iterates
|
89
|
+
# over the results returned by a single API call.) Use with caution.
|
90
|
+
#
|
91
|
+
# @param [Integer] request_limit The upper limit of API requests to
|
92
|
+
# make to load all snapshots. Default is no limit.
|
93
|
+
# @yield [snapshot] The block for accessing each snapshot.
|
94
|
+
# @yieldparam [Snapshot] snapshot The snapshot object.
|
95
|
+
#
|
96
|
+
# @return [Enumerator]
|
97
|
+
#
|
98
|
+
# @example Iterating each snapshot by passing a block:
|
99
|
+
# require "google/cloud/pubsub"
|
100
|
+
#
|
101
|
+
# pubsub = Google::Cloud::PubSub.new
|
102
|
+
#
|
103
|
+
# snapshots = pubsub.snapshots
|
104
|
+
# snapshots.all do |snapshot|
|
105
|
+
# puts snapshot.name
|
106
|
+
# end
|
107
|
+
#
|
108
|
+
# @example Using the enumerator by not passing a block:
|
109
|
+
# require "google/cloud/pubsub"
|
110
|
+
#
|
111
|
+
# pubsub = Google::Cloud::PubSub.new
|
112
|
+
#
|
113
|
+
# snapshots = pubsub.snapshots
|
114
|
+
# all_names = snapshots.all.map do |snapshot|
|
115
|
+
# snapshot.name
|
116
|
+
# end
|
117
|
+
#
|
118
|
+
# @example Limit the number of API calls made:
|
119
|
+
# require "google/cloud/pubsub"
|
120
|
+
#
|
121
|
+
# pubsub = Google::Cloud::PubSub.new
|
122
|
+
#
|
123
|
+
# snapshots = pubsub.snapshots
|
124
|
+
# snapshots.all(request_limit: 10) do |snapshot|
|
125
|
+
# puts snapshot.name
|
126
|
+
# end
|
127
|
+
#
|
128
|
+
def all request_limit: nil, &block
|
129
|
+
request_limit = request_limit.to_i if request_limit
|
130
|
+
return enum_for :all, request_limit: request_limit unless block_given?
|
131
|
+
results = self
|
132
|
+
loop do
|
133
|
+
results.each(&block)
|
134
|
+
if request_limit
|
135
|
+
request_limit -= 1
|
136
|
+
break if request_limit.negative?
|
137
|
+
end
|
138
|
+
break unless results.next?
|
139
|
+
results = results.next
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
##
|
144
|
+
# @private New Snapshots::List from a
|
145
|
+
# Google::Cloud::PubSub::V1::ListSnapshotsRequest object.
|
146
|
+
def self.from_grpc grpc_list, service, max = nil
|
147
|
+
subs = new(Array(grpc_list.snapshots).map do |grpc|
|
148
|
+
Snapshot.from_grpc grpc, service
|
149
|
+
end)
|
150
|
+
token = grpc_list.next_page_token
|
151
|
+
token = nil if token == "".freeze
|
152
|
+
subs.instance_variable_set :@token, token
|
153
|
+
subs.instance_variable_set :@service, service
|
154
|
+
subs.instance_variable_set :@max, max
|
155
|
+
subs
|
156
|
+
end
|
157
|
+
|
158
|
+
protected
|
159
|
+
|
160
|
+
##
|
161
|
+
# @private Raise an error unless an active connection to the service
|
162
|
+
# is available.
|
163
|
+
def ensure_service!
|
164
|
+
raise "Must have active connection to service" unless @service
|
165
|
+
end
|
166
|
+
|
167
|
+
def next_snapshots
|
168
|
+
options = { prefix: @prefix, token: @token, max: @max }
|
169
|
+
grpc = @service.list_snapshots options
|
170
|
+
self.class.from_grpc grpc, @service, @max
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
Pubsub = PubSub unless const_defined? :Pubsub
|
177
|
+
end
|
178
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
# Copyright 2017 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
|
+
require "google/cloud/pubsub/snapshot/list"
|
18
|
+
require "google/cloud/pubsub/v1"
|
19
|
+
|
20
|
+
module Google
|
21
|
+
module Cloud
|
22
|
+
module PubSub
|
23
|
+
##
|
24
|
+
# # Snapshot
|
25
|
+
#
|
26
|
+
# A named resource created from a subscription to retain a stream of
|
27
|
+
# messages from a topic. A snapshot is guaranteed to retain:
|
28
|
+
#
|
29
|
+
# * The existing backlog on the subscription. More precisely, this is
|
30
|
+
# defined as the messages in the subscription's backlog that are
|
31
|
+
# unacknowledged upon the successful completion of the
|
32
|
+
# `create_snapshot` operation; as well as:
|
33
|
+
# * Any messages published to the subscription's topic following the
|
34
|
+
# successful completion of the `create_snapshot` operation.
|
35
|
+
#
|
36
|
+
# @example
|
37
|
+
# require "google/cloud/pubsub"
|
38
|
+
#
|
39
|
+
# pubsub = Google::Cloud::PubSub.new
|
40
|
+
# sub = pubsub.subscription "my-sub"
|
41
|
+
#
|
42
|
+
# snapshot = sub.create_snapshot "my-snapshot"
|
43
|
+
# snapshot.name #=> "projects/my-project/snapshots/my-snapshot"
|
44
|
+
#
|
45
|
+
class Snapshot
|
46
|
+
##
|
47
|
+
# @private The Service object.
|
48
|
+
attr_accessor :service
|
49
|
+
|
50
|
+
##
|
51
|
+
# @private The gRPC Google::Cloud::PubSub::V1::Snapshot object.
|
52
|
+
attr_accessor :grpc
|
53
|
+
|
54
|
+
##
|
55
|
+
# @private Create an empty {Snapshot} object.
|
56
|
+
def initialize
|
57
|
+
@service = nil
|
58
|
+
@grpc = Google::Cloud::PubSub::V1::Snapshot.new
|
59
|
+
end
|
60
|
+
|
61
|
+
##
|
62
|
+
# The name of the snapshot.
|
63
|
+
#
|
64
|
+
# @return [String] A fully-qualified snapshot name in the form
|
65
|
+
# `projects/{project_id}/snapshots/{snapshot_id}`.
|
66
|
+
def name
|
67
|
+
@grpc.name
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# The {Topic} from which this snapshot is retaining messages.
|
72
|
+
#
|
73
|
+
# @return [Topic]
|
74
|
+
#
|
75
|
+
# @example
|
76
|
+
# require "google/cloud/pubsub"
|
77
|
+
#
|
78
|
+
# pubsub = Google::Cloud::PubSub.new
|
79
|
+
# sub = pubsub.subscription "my-sub"
|
80
|
+
#
|
81
|
+
# snapshot = sub.create_snapshot "my-snapshot"
|
82
|
+
# snapshot.topic.name #=> "projects/my-project/topics/my-topic"
|
83
|
+
#
|
84
|
+
def topic
|
85
|
+
Topic.from_name @grpc.topic, service
|
86
|
+
end
|
87
|
+
|
88
|
+
##
|
89
|
+
# The snapshot is guaranteed to exist up until this time.
|
90
|
+
# A newly-created snapshot expires no later than 7 days from the time of
|
91
|
+
# its creation. Its exact lifetime is determined at creation by the
|
92
|
+
# existing backlog in the source subscription. Specifically, the
|
93
|
+
# lifetime of the snapshot is 7 days - (age of oldest unacked message in
|
94
|
+
# the subscription). For example, consider a subscription whose oldest
|
95
|
+
# unacked message is 3 days old. If a snapshot is created from this
|
96
|
+
# subscription, the snapshot -- which will always capture this 3-day-old
|
97
|
+
# backlog as long as the snapshot exists -- will expire in 4 days.
|
98
|
+
#
|
99
|
+
# @return [Time] The time until which the snapshot is guaranteed to
|
100
|
+
# exist.
|
101
|
+
#
|
102
|
+
# @example
|
103
|
+
# require "google/cloud/pubsub"
|
104
|
+
#
|
105
|
+
# pubsub = Google::Cloud::PubSub.new
|
106
|
+
# sub = pubsub.subscription "my-sub"
|
107
|
+
#
|
108
|
+
# snapshot = sub.create_snapshot "my-snapshot"
|
109
|
+
# snapshot.topic.name #=> "projects/my-project/topics/my-topic"
|
110
|
+
# snapshot.expiration_time
|
111
|
+
#
|
112
|
+
def expiration_time
|
113
|
+
self.class.timestamp_from_grpc @grpc.expire_time
|
114
|
+
end
|
115
|
+
|
116
|
+
##
|
117
|
+
# A hash of user-provided labels associated with this snapshot.
|
118
|
+
# Labels can be used to organize and group snapshots.See [Creating and
|
119
|
+
# Managing Labels](https://cloud.google.com/pubsub/docs/labels).
|
120
|
+
#
|
121
|
+
# The returned hash is frozen and changes are not allowed. Use
|
122
|
+
# {#labels=} to update the labels for this snapshot.
|
123
|
+
#
|
124
|
+
# @return [Hash] The frozen labels hash.
|
125
|
+
#
|
126
|
+
def labels
|
127
|
+
@grpc.labels.to_h.freeze
|
128
|
+
end
|
129
|
+
|
130
|
+
##
|
131
|
+
# Sets the hash of user-provided labels associated with this
|
132
|
+
# snapshot. Labels can be used to organize and group snapshots.
|
133
|
+
# Label keys and values can be no longer than 63 characters, can only
|
134
|
+
# contain lowercase letters, numeric characters, underscores and dashes.
|
135
|
+
# International characters are allowed. Label values are optional. Label
|
136
|
+
# keys must start with a letter and each label in the list must have a
|
137
|
+
# different key. See [Creating and Managing
|
138
|
+
# Labels](https://cloud.google.com/pubsub/docs/labels).
|
139
|
+
#
|
140
|
+
# @param [Hash] new_labels The new labels hash.
|
141
|
+
#
|
142
|
+
def labels= new_labels
|
143
|
+
raise ArgumentError, "Value must be a Hash" if new_labels.nil?
|
144
|
+
labels_map = Google::Protobuf::Map.new :string, :string
|
145
|
+
Hash(new_labels).each { |k, v| labels_map[String(k)] = String(v) }
|
146
|
+
update_grpc = @grpc.dup
|
147
|
+
update_grpc.labels = labels_map
|
148
|
+
@grpc = service.update_snapshot update_grpc, :labels
|
149
|
+
end
|
150
|
+
|
151
|
+
##
|
152
|
+
# Removes an existing snapshot. All messages retained in the snapshot
|
153
|
+
# are immediately dropped. After a snapshot is deleted, a new one may be
|
154
|
+
# created with the same name, but the new one has no association with
|
155
|
+
# the old snapshot or its subscription, unless the same subscription is
|
156
|
+
# specified.
|
157
|
+
#
|
158
|
+
# @return [Boolean] Returns `true` if the snapshot was deleted.
|
159
|
+
#
|
160
|
+
# @example
|
161
|
+
# require "google/cloud/pubsub"
|
162
|
+
#
|
163
|
+
# pubsub = Google::Cloud::PubSub.new
|
164
|
+
#
|
165
|
+
# pubsub.snapshots.each do |snapshot|
|
166
|
+
# snapshot.delete
|
167
|
+
# end
|
168
|
+
#
|
169
|
+
def delete
|
170
|
+
ensure_service!
|
171
|
+
service.delete_snapshot name
|
172
|
+
true
|
173
|
+
end
|
174
|
+
|
175
|
+
##
|
176
|
+
# @private New Snapshot from a Google::Cloud::PubSub::V1::Snapshot
|
177
|
+
# object.
|
178
|
+
def self.from_grpc grpc, service
|
179
|
+
new.tap do |f|
|
180
|
+
f.grpc = grpc
|
181
|
+
f.service = service
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
##
|
186
|
+
# @private Get a Time object from a Google::Protobuf::Timestamp object.
|
187
|
+
def self.timestamp_from_grpc grpc_timestamp
|
188
|
+
return nil if grpc_timestamp.nil?
|
189
|
+
Time.at grpc_timestamp.seconds, Rational(grpc_timestamp.nanos, 1000)
|
190
|
+
end
|
191
|
+
|
192
|
+
protected
|
193
|
+
|
194
|
+
##
|
195
|
+
# @private Raise an error unless an active connection to the service is
|
196
|
+
# available.
|
197
|
+
def ensure_service!
|
198
|
+
raise "Must have active connection to service" unless service
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
Pubsub = PubSub unless const_defined? :Pubsub
|
204
|
+
end
|
205
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# Copyright 2017 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
|
+
module Google
|
17
|
+
module Cloud
|
18
|
+
module PubSub
|
19
|
+
class Subscriber
|
20
|
+
# @private
|
21
|
+
class EnumeratorQueue
|
22
|
+
def initialize sentinel = nil
|
23
|
+
@queue = Queue.new
|
24
|
+
@sentinel = sentinel
|
25
|
+
end
|
26
|
+
|
27
|
+
def push obj
|
28
|
+
@queue.push obj
|
29
|
+
end
|
30
|
+
|
31
|
+
def quit_and_dump_queue
|
32
|
+
objs = []
|
33
|
+
objs << @queue.pop until @queue.empty?
|
34
|
+
# Signal that the enumerator is ready to end
|
35
|
+
@queue.push @sentinel
|
36
|
+
objs
|
37
|
+
end
|
38
|
+
|
39
|
+
def each
|
40
|
+
return enum_for :each unless block_given?
|
41
|
+
|
42
|
+
loop do
|
43
|
+
obj = @queue.pop
|
44
|
+
break if obj.equal? @sentinel
|
45
|
+
yield obj
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
Pubsub = PubSub unless const_defined? :Pubsub
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
# Copyright 2017 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 "monitor"
|
17
|
+
|
18
|
+
module Google
|
19
|
+
module Cloud
|
20
|
+
module PubSub
|
21
|
+
class Subscriber
|
22
|
+
##
|
23
|
+
# @private
|
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
|
+
|
31
|
+
include MonitorMixin
|
32
|
+
|
33
|
+
attr_reader :stream
|
34
|
+
attr_reader :limit
|
35
|
+
attr_reader :bytesize
|
36
|
+
attr_reader :extension
|
37
|
+
attr_reader :max_duration_per_lease_extension
|
38
|
+
attr_reader :use_legacy_flow_control
|
39
|
+
|
40
|
+
def initialize stream, limit:, bytesize:, extension:, max_duration_per_lease_extension:,
|
41
|
+
use_legacy_flow_control:
|
42
|
+
super()
|
43
|
+
@stream = stream
|
44
|
+
@limit = limit
|
45
|
+
@bytesize = bytesize
|
46
|
+
@extension = extension
|
47
|
+
@max_duration_per_lease_extension = max_duration_per_lease_extension
|
48
|
+
@use_legacy_flow_control = use_legacy_flow_control
|
49
|
+
@inventory = {}
|
50
|
+
@wait_cond = new_cond
|
51
|
+
end
|
52
|
+
|
53
|
+
def ack_ids
|
54
|
+
@inventory.keys
|
55
|
+
end
|
56
|
+
|
57
|
+
def add *rec_msgs
|
58
|
+
rec_msgs.flatten!
|
59
|
+
rec_msgs.compact!
|
60
|
+
return if rec_msgs.empty?
|
61
|
+
|
62
|
+
synchronize do
|
63
|
+
rec_msgs.each do |rec_msg|
|
64
|
+
@inventory[rec_msg.ack_id] = InventoryItem.from rec_msg
|
65
|
+
end
|
66
|
+
@wait_cond.broadcast
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def remove *ack_ids
|
71
|
+
ack_ids.flatten!
|
72
|
+
ack_ids.compact!
|
73
|
+
return if ack_ids.empty?
|
74
|
+
|
75
|
+
synchronize do
|
76
|
+
@inventory.delete_if { |ack_id, _| ack_ids.include? ack_id }
|
77
|
+
@wait_cond.broadcast
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def remove_expired!
|
82
|
+
synchronize do
|
83
|
+
extension_time = Time.new - extension
|
84
|
+
@inventory.delete_if { |_ack_id, item| item.pulled_at < extension_time }
|
85
|
+
@wait_cond.broadcast
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def count
|
90
|
+
synchronize do
|
91
|
+
@inventory.count
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def total_bytesize
|
96
|
+
synchronize do
|
97
|
+
@inventory.values.sum(&:bytesize)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def empty?
|
102
|
+
synchronize do
|
103
|
+
@inventory.empty?
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def start
|
108
|
+
@background_thread ||= Thread.new { background_run }
|
109
|
+
|
110
|
+
self
|
111
|
+
end
|
112
|
+
|
113
|
+
def stop
|
114
|
+
synchronize do
|
115
|
+
@stopped = true
|
116
|
+
@wait_cond.broadcast
|
117
|
+
end
|
118
|
+
|
119
|
+
self
|
120
|
+
end
|
121
|
+
|
122
|
+
def stopped?
|
123
|
+
synchronize { @stopped }
|
124
|
+
end
|
125
|
+
|
126
|
+
def full?
|
127
|
+
synchronize do
|
128
|
+
@inventory.count >= limit || @inventory.values.sum(&:bytesize) >= bytesize
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
protected
|
133
|
+
|
134
|
+
def background_run
|
135
|
+
delay_target = nil
|
136
|
+
|
137
|
+
until stopped?
|
138
|
+
if empty?
|
139
|
+
delay_target = nil
|
140
|
+
|
141
|
+
synchronize { @wait_cond.wait } # wait until broadcast
|
142
|
+
next
|
143
|
+
end
|
144
|
+
|
145
|
+
delay_target ||= calc_target
|
146
|
+
delay_gap = delay_target - Time.now
|
147
|
+
|
148
|
+
unless delay_gap.positive?
|
149
|
+
delay_target = calc_target
|
150
|
+
stream.renew_lease!
|
151
|
+
next
|
152
|
+
end
|
153
|
+
|
154
|
+
synchronize { @wait_cond.wait delay_gap }
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def calc_target
|
159
|
+
Time.now + calc_delay
|
160
|
+
end
|
161
|
+
|
162
|
+
def calc_delay
|
163
|
+
delay = (stream.subscriber.deadline - 3) * rand(0.8..0.9)
|
164
|
+
delay = [delay, max_duration_per_lease_extension].min if max_duration_per_lease_extension.positive?
|
165
|
+
delay
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
Pubsub = PubSub unless const_defined? :Pubsub
|
172
|
+
end
|
173
|
+
end
|