protobuf-nats 0.8.0 → 0.9.0.pre1

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
  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