google-cloud-pubsub 0.20.0 → 2.6.1
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.
- 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
|