protobuf-nats 0.8.0 → 0.9.0.pre1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 37d13406765b84608feb5c1b8edc2b694dd9b51e
4
- data.tar.gz: 3a26cd0d3a925426a42448761abedfa7cd4e80e5
3
+ metadata.gz: b965b64f467078a814cd456821efec903fcff030
4
+ data.tar.gz: 83f040bbc6b8d48d5421fb9f31c44278b7f5ef63
5
5
  SHA512:
6
- metadata.gz: 496a65ec0285610c3c44b913af26c6457e7cdd7fae9ec925d9826dfb523a090a41809256dd39f5822bdaafe5a3f412ab21d86c9cc1f0705a9b9ea2876b4e5940
7
- data.tar.gz: d5f9f0460adfd3812c236257afa98256790be5bb30029dd2756eb6c9bc8020ec146ae9406db2e8f793b2b753be87048cbb001f01317a7902733ca0f30e5ed095
6
+ metadata.gz: 2fce53579733468be93dece666e78ec435280fdb143d9155ea8302c43f70a4f59efcb5af8668eb5c2af85d1d415631fd5bcb2300bef8def906a3afc9ff58a7cd
7
+ data.tar.gz: 23bf375eeae757647bedd11c19f2b02cf70d9d4b841820003856e87c8148963e4e4ca5b446d17050beefd966c1ab109315b33f9cc3f3434a74ac336b0900e910
@@ -1,3 +1,4 @@
1
+ require "connection_pool"
1
2
  require "protobuf/nats"
2
3
  require "protobuf/rpc/connectors/base"
3
4
  require "monitor"
@@ -5,6 +6,30 @@ require "monitor"
5
6
  module Protobuf
6
7
  module Nats
7
8
  class Client < ::Protobuf::Rpc::Connectors::Base
9
+ # Structure to hold subscription and inbox to use within pool
10
+ SubscriptionInbox = ::Struct.new(:subscription, :inbox) do
11
+ def swap(sub_inbox)
12
+ self.subscription = sub_inbox.subscription
13
+ self.inbox = sub_inbox.inbox
14
+ end
15
+ end
16
+
17
+ def self.subscription_pool
18
+ @subscription_pool ||= ::ConnectionPool.new(:size => subscription_pool_size, :timeout => 0.1) do
19
+ inbox = ::Protobuf::Nats.client_nats_connection.new_inbox
20
+
21
+ SubscriptionInbox.new(::Protobuf::Nats.client_nats_connection.subscribe(inbox), inbox)
22
+ end
23
+ end
24
+
25
+ def self.subscription_pool_size
26
+ @subscription_pool_size ||= if ::ENV.key?("PB_NATS_CLIENT_SUBSCRIPTION_POOL_SIZE")
27
+ ::ENV["PB_NATS_CLIENT_SUBSCRIPTION_POOL_SIZE"].to_i
28
+ else
29
+ 0
30
+ end
31
+ end
32
+
8
33
  def initialize(options)
9
34
  # may need to override to setup connection at this stage ... may also do on load of class
10
35
  super
@@ -13,6 +38,32 @@ module Protobuf
13
38
  ::Protobuf::Nats.start_client_nats_connection
14
39
  end
15
40
 
41
+ def new_subscription_inbox
42
+ nats = ::Protobuf::Nats.client_nats_connection
43
+ inbox = nats.new_inbox
44
+ sub = if use_subscription_pooling?
45
+ nats.subscribe(inbox)
46
+ else
47
+ nats.subscribe(inbox, :max => 2)
48
+ end
49
+
50
+ SubscriptionInbox.new(sub, inbox)
51
+ end
52
+
53
+ def with_subscription
54
+ return_value = nil
55
+
56
+ if use_subscription_pooling?
57
+ self.class.subscription_pool.with do |sub_inbox|
58
+ return_value = yield sub_inbox
59
+ end
60
+ else
61
+ return_value = yield new_subscription_inbox
62
+ end
63
+
64
+ return_value
65
+ end
66
+
16
67
  def close_connection
17
68
  # no-op (I think for now), the connection to server is persistent
18
69
  end
@@ -69,7 +120,17 @@ module Protobuf
69
120
  end
70
121
  end
71
122
 
123
+ def use_subscription_pooling?
124
+ return @use_subscription_pooling unless @use_subscription_pooling.nil?
125
+ @use_subscription_pooling = self.class.subscription_pool_size > 0
126
+ end
127
+
72
128
  def send_request
129
+ if use_subscription_pooling?
130
+ available = self.class.subscription_pool.instance_variable_get("@available")
131
+ ::ActiveSupport::Notifications.instrument "client.pool_availble_size.protobuf-nats", available.length
132
+ end
133
+
73
134
  ::ActiveSupport::Notifications.instrument "client.request_duration.protobuf-nats" do
74
135
  send_request_through_nats
75
136
  end
@@ -96,11 +157,11 @@ module Protobuf
96
157
  sleep((interval + nack_backoff_splay)/1000.0)
97
158
  next
98
159
  end
160
+
99
161
  break
100
162
  end
101
163
 
102
164
  parse_response
103
-
104
165
  rescue ::Protobuf::Nats::Errors::IOException => error
105
166
  ::Protobuf::Nats.log_error(error)
106
167
 
@@ -137,34 +198,41 @@ module Protobuf
137
198
  timeout = opts[:timeout] || 60
138
199
 
139
200
  nats = ::Protobuf::Nats.client_nats_connection
140
- inbox = nats.new_inbox
141
201
 
142
202
  # Publish to server
143
- sub = nats.subscribe(inbox, :max => 2)
144
- nats.publish(subject, data, inbox)
145
-
146
- # Wait for reply
147
- first_message = nats.next_message(sub, ack_timeout)
148
- return :ack_timeout if first_message.nil?
149
- first_message_data = first_message.data
150
- return :nack if first_message_data == ::Protobuf::Nats::Messages::NACK
151
-
152
- second_message = nats.next_message(sub, timeout)
153
- second_message_data = second_message.nil? ? nil : second_message.data
154
-
155
- # Check messages
156
- response = case ::Protobuf::Nats::Messages::ACK
157
- when first_message_data then second_message_data
158
- when second_message_data then first_message_data
159
- else return :ack_timeout
160
- end
161
-
162
- fail(::Protobuf::Nats::Errors::ResponseTimeout, subject) unless response
163
-
164
- response
165
- ensure
166
- # Ensure we don't leave a subscriptiosn sitting around.
167
- nats.unsubscribe(sub)
203
+ with_subscription do |sub_inbox|
204
+ begin
205
+ completed_request = false
206
+ nats.publish(subject, data, sub_inbox.inbox)
207
+
208
+ # Wait for reply
209
+ first_message = nats.next_message(sub_inbox.subscription, ack_timeout)
210
+ return :ack_timeout if first_message.nil?
211
+
212
+ first_message_data = first_message.data
213
+ return :nack if first_message_data == ::Protobuf::Nats::Messages::NACK
214
+
215
+ second_message = nats.next_message(sub_inbox.subscription, timeout)
216
+ second_message_data = second_message.nil? ? nil : second_message.data
217
+
218
+ # Check messages
219
+ response = case ::Protobuf::Nats::Messages::ACK
220
+ when first_message_data then second_message_data
221
+ when second_message_data then first_message_data
222
+ else return :ack_timeout
223
+ end
224
+
225
+ fail(::Protobuf::Nats::Errors::ResponseTimeout, subject) unless response
226
+
227
+ completed_request = true
228
+ response
229
+ ensure
230
+ if !completed_request
231
+ nats.unsubscribe(sub_inbox.subscription)
232
+ sub_inbox.swap(new_subscription_inbox) # this line replaces the sub_inbox in the connection pool if necessary
233
+ end
234
+ end
235
+ end
168
236
  end
169
237
 
170
238
  else
@@ -1,5 +1,5 @@
1
1
  module Protobuf
2
2
  module Nats
3
- VERSION = "0.8.0"
3
+ VERSION = "0.9.0.pre1"
4
4
  end
5
5
  end
@@ -31,6 +31,7 @@ Gem::Specification.new do |spec|
31
31
  spec.require_paths = ["lib"]
32
32
 
33
33
  spec.add_runtime_dependency "activesupport", ">= 3.2"
34
+ spec.add_runtime_dependency "connection_pool"
34
35
  spec.add_runtime_dependency "protobuf", "~> 3.7", ">= 3.7.2"
35
36
  spec.add_runtime_dependency "nats-pure"
36
37
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: protobuf-nats
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0.pre1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Dewitt
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-10-20 00:00:00.000000000 Z
11
+ date: 2017-11-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '3.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: connection_pool
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: protobuf
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -180,12 +194,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
180
194
  version: '0'
181
195
  required_rubygems_version: !ruby/object:Gem::Requirement
182
196
  requirements:
183
- - - ">="
197
+ - - ">"
184
198
  - !ruby/object:Gem::Version
185
- version: '0'
199
+ version: 1.3.1
186
200
  requirements: []
187
201
  rubyforge_project:
188
- rubygems_version: 2.6.13
202
+ rubygems_version: 2.5.1
189
203
  signing_key:
190
204
  specification_version: 4
191
205
  summary: ruby-protobuf client/server for nats