protobuf-nats 0.10.5 → 0.11.0.pre0

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
  SHA256:
3
- metadata.gz: c2187c7b268795df3d9cb72b75d4bf51456c055bd00253cdc2fc25385cdbb988
4
- data.tar.gz: bd286511daf03a39bf93ad1aa74d8f044b7b1019cb9eb043c40c663e4950f3a2
3
+ metadata.gz: 0fa8475a4054e8c99c04c30193f773ccca511efbf8412a8d26fa162dbb024f4c
4
+ data.tar.gz: 66a92c3b49be6df8f0014a219d9691b847b7432e00d685722739190c30ba9ac5
5
5
  SHA512:
6
- metadata.gz: 2f36143434fadea654a256c365fde72df2932510c8c1430408095d14fd426b512404725c67e621d6b13df9a8aef266fef3a9f4a3945a2d3e6ccb329cc70aa641
7
- data.tar.gz: a79b514f718ea525bde3095de4f5568849f8321c67c703096386bbef74cde0599b4f952ee70b12b6b22b338ea39666faef3d2c6af74585852f3972831adcb36b
6
+ metadata.gz: 0cce76f4edd08e182c665ac53fc5d69e39ccb764855f1335220a197a98b18fa2012c73862071b77b1f0e32a2c8b7d7e60b5c652fe458151733dc3f7f79970c71
7
+ data.tar.gz: a024fd949c96297de7d853bb182503716ed449b1500f217660e8e1bcf4fb2639ca0b12840c002732ef415e9889cea39880b638d2fb3f1859405f750185b4d2d1
data/.travis.yml CHANGED
@@ -1,16 +1,12 @@
1
1
  sudo: false
2
2
  language: ruby
3
- jdk:
4
- - openjdk8
3
+ jdk: openjdk8
5
4
  rvm:
6
5
  - 2.3.0
7
- - 2.7.0
8
6
  - jruby-9.1.7.0
9
- - jruby-9.2.13.0
10
7
  before_install:
11
- # Install and start gnatsd
12
- - ./scripts/install_gnatsd.sh
13
- - $HOME/nats-server/nats-server &
14
- # Install deps for project
15
8
  - gem install bundler
16
9
  - gem update --system
10
+ - wget https://github.com/nats-io/gnatsd/releases/download/v1.3.0/gnatsd-v1.3.0-linux-amd64.zip
11
+ - unzip gnatsd-v1.3.0-linux-amd64.zip
12
+ - ./gnatsd-v1.3.0-linux-amd64/gnatsd &
data/README.md CHANGED
@@ -154,11 +154,9 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
154
154
 
155
155
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
156
156
 
157
- The java-nats client is temporarily forked to support jruby > 9.2.10.0. The living branch for that is here: https://github.com/film42/java-nats/tree/jruby-compat. This will be removed when we upgrade to the new nats.java client.
158
-
159
157
  ## Contributing
160
158
 
161
- Bug reports and pull requests are welcome on GitHub at https://github.com/mxenabled/protobuf-nats.
159
+ Bug reports and pull requests are welcome on GitHub at https://github.com/abrandoned/protobuf-nats.
162
160
 
163
161
 
164
162
  ## License
Binary file
@@ -151,12 +151,12 @@ module Protobuf
151
151
  when :ack_timeout
152
152
  ::ActiveSupport::Notifications.instrument "client.request_timeout.protobuf-nats"
153
153
  next if (retries -= 1) > 0
154
- raise ::Protobuf::Nats::Errors::RequestTimeout, formatted_service_and_method_name
154
+ raise ::Protobuf::Nats::Errors::RequestTimeout
155
155
  when :nack
156
156
  ::ActiveSupport::Notifications.instrument "client.request_nack.protobuf-nats"
157
157
  interval = nack_backoff_intervals[nack_retry]
158
158
  nack_retry += 1
159
- raise ::Protobuf::Nats::Errors::RequestTimeout, formatted_service_and_method_name if interval.nil?
159
+ raise ::Protobuf::Nats::Errors::RequestTimeout if interval.nil?
160
160
  sleep((interval + nack_backoff_splay)/1000.0)
161
161
  next
162
162
  end
@@ -186,12 +186,6 @@ module Protobuf
186
186
  end
187
187
  end
188
188
 
189
- def formatted_service_and_method_name
190
- klass = @options[:service]
191
- method_name = @options[:method]
192
- "#{klass}##{method_name}"
193
- end
194
-
195
189
  # The Java nats client offers better message queueing so we're going to use
196
190
  # that over locking ourselves. This split in code isn't great, but we can
197
191
  # refactor this later.
@@ -213,7 +207,7 @@ module Protobuf
213
207
  begin
214
208
  completed_request = false
215
209
 
216
- if !sub_inbox.subscription.is_valid # replace the subscription if is has been pooled but is no longer valid (maybe a reconnect)
210
+ if !sub_inbox.subscription.is_active # replace the subscription if is has been pooled but is no longer valid (maybe a reconnect)
217
211
  nats.unsubscribe(sub_inbox.subscription)
218
212
  sub_inbox.swap(new_subscription_inbox) # this line replaces the sub_inbox in the connection pool if necessary
219
213
  end
@@ -237,7 +231,7 @@ module Protobuf
237
231
  else return :ack_timeout
238
232
  end
239
233
 
240
- fail(::Protobuf::Nats::Errors::ResponseTimeout, formatted_service_and_method_name) unless response
234
+ fail(::Protobuf::Nats::Errors::ResponseTimeout, subject) unless response
241
235
 
242
236
  completed_request = true
243
237
  response
@@ -293,7 +287,7 @@ module Protobuf
293
287
  else return :ack_timeout
294
288
  end
295
289
 
296
- fail(::Protobuf::Nats::Errors::ResponseTimeout, formatted_service_and_method_name) unless response
290
+ fail(::Protobuf::Nats::Errors::ResponseTimeout, subject) unless response
297
291
 
298
292
  response
299
293
  ensure
@@ -39,13 +39,8 @@ module Protobuf
39
39
  yaml_config = {}
40
40
  config_path = ENV["PROTOBUF_NATS_CONFIG_PATH"] || ::File.join("config", "protobuf_nats.yml")
41
41
  absolute_config_path = ::File.expand_path(config_path)
42
- if ::File.exist?(absolute_config_path)
43
- # Psych 4 and newer requires unsafe_load_file in order for aliases to be used
44
- yaml_config = if ::YAML.respond_to?(:unsafe_load_file)
45
- ::YAML.unsafe_load_file(absolute_config_path)[env]
46
- else
47
- ::YAML.load_file(absolute_config_path)[env]
48
- end
42
+ if ::File.exists?(absolute_config_path)
43
+ yaml_config = ::YAML.load_file(absolute_config_path)[env]
49
44
  end
50
45
 
51
46
  DEFAULTS.each_pair do |key, value|
@@ -1,13 +1,13 @@
1
1
  module Protobuf
2
2
  module Nats
3
3
  module Errors
4
- class ClientError < ::StandardError
4
+ class Base < ::StandardError
5
5
  end
6
6
 
7
- class RequestTimeout < ClientError
7
+ class RequestTimeout < Base
8
8
  end
9
9
 
10
- class ResponseTimeout < ClientError
10
+ class ResponseTimeout < Base
11
11
  end
12
12
 
13
13
  class MriIOException < ::StandardError
@@ -3,12 +3,82 @@ ext_base = ::File.join(::File.dirname(__FILE__), '..', '..', '..', 'ext')
3
3
  require ::File.join(ext_base, "jars/slf4j-api-1.7.25.jar")
4
4
  require ::File.join(ext_base, "jars/slf4j-simple-1.7.25.jar")
5
5
  require ::File.join(ext_base, "jars/gson-2.6.2.jar")
6
- require ::File.join(ext_base, "jars/jnats-1.1-SNAPSHOT.jar")
6
+ require ::File.join(ext_base, "jars/jnats-2.6.0.jar")
7
7
 
8
8
  module Protobuf
9
9
  module Nats
10
10
  class JNats
11
- attr_reader :connection, :options
11
+ attr_reader :connection, :dispatcher, :options
12
+
13
+ class MessageHandlerProxy
14
+ include ::Java::IoNatsClient::MessageHandler
15
+
16
+ def self.empty
17
+ new {}
18
+ end
19
+
20
+ def initialize(&block)
21
+ @cb = block
22
+ end
23
+
24
+ def onMessage(message)
25
+ @cb.call(message.getData.to_s, message.getReplyTo, message.getSubject)
26
+ end
27
+ end
28
+
29
+ class ConnectionListener
30
+ include ::Java::IoNatsClient::ConnectionListener
31
+
32
+ def initialize
33
+ @on_reconnect_cb = lambda {}
34
+ @on_disconnect_cb = lambda {}
35
+ @on_close_cb = lambda {}
36
+ end
37
+
38
+ def on_close(&block); @on_close_cb = block; end
39
+ def on_disconnect(&block); @on_disconnect_cb = block; end
40
+ def on_reconnect(&block); @on_reconnect_cb = block; end
41
+
42
+ def connectionEvent(conn, event_type)
43
+ case event_type
44
+ when ::Java::IoNatsClient::ConnectionListener::Events::RECONNECTED
45
+ @on_reconnect_cb.call
46
+ when ::Java::IoNatsClient::ConnectionListener::Events::DISCONNECTED
47
+ @on_disconnect_cb.call
48
+ when ::Java::IoNatsClient::ConnectionListener::Events::CLOSED
49
+ @on_close_cb.call
50
+ end
51
+ end
52
+ end
53
+
54
+ class ErrorListener
55
+ include ::Java::IoNatsClient::ErrorListener
56
+
57
+ def initialize
58
+ @on_error_cb = lambda { |_error| }
59
+ @on_exception_cb = lambda { |_exception| }
60
+ @on_slow_consumer_cb = lambda { |_consumer| }
61
+ end
62
+
63
+ def on_error(&block)
64
+ return if block.nil? || block.arity != 1
65
+ @on_error_cb = block
66
+ end
67
+
68
+ def on_exception(&block)
69
+ return if block.nil? || block.arity != 1
70
+ @on_exception_cb = block
71
+ end
72
+
73
+ def on_slow_consumer(&block)
74
+ return if block.nil? || block.arity != 1
75
+ @on_slow_consumer_cb = block
76
+ end
77
+
78
+ def errorOccurred(_conn, error); @on_error_cb.call(error); end
79
+ def exceptionOccurred(_conn, exception); @on_exception_cb.call(exception); end
80
+ def slowConsumerDetected(_conn, consumer); @on_slow_consumer_cb.call(consumer); end
81
+ end
12
82
 
13
83
  class Message
14
84
  attr_reader :data, :subject, :reply
@@ -21,10 +91,9 @@ module Protobuf
21
91
  end
22
92
 
23
93
  def initialize
24
- @on_error_cb = lambda {|error|}
25
- @on_reconnect_cb = lambda {}
26
- @on_disconnect_cb = lambda {}
27
- @on_close_cb = lambda {}
94
+ @connection_listener = ConnectionListener.new
95
+ @error_listener = ErrorListener.new
96
+
28
97
  @options = nil
29
98
  @subz_cbs = {}
30
99
  @subz_mutex = ::Mutex.new
@@ -34,35 +103,26 @@ module Protobuf
34
103
  @options ||= options
35
104
 
36
105
  servers = options[:servers] || ["nats://localhost:4222"]
37
- servers = [servers].flatten.map { |uri_string| java.net.URI.new(uri_string) }
38
- connection_factory = ::Java::IoNatsClient::ConnectionFactory.new
39
- connection_factory.setServers(servers)
40
- connection_factory.setMaxReconnect(options[:max_reconnect_attempts])
106
+ servers = [servers].flatten
107
+
108
+ builder = ::Java::IoNatsClient::Options::Builder.new
109
+ builder.servers(servers)
110
+ builder.maxReconnects(options[:max_reconnect_attempts])
111
+ builder.errorListener(@error_listener)
41
112
 
42
113
  # Shrink the pending buffer to always raise an error and let the caller retry.
43
114
  if options[:disable_reconnect_buffer]
44
- connection_factory.setReconnectBufSize(1)
115
+ builder.reconnectBufferSize(1)
45
116
  end
46
117
 
47
- # Setup callbacks
48
- connection_factory.setDisconnectedCallback { |event| @on_disconnect_cb.call }
49
- connection_factory.setReconnectedCallback { |_event| @on_reconnect_cb.call }
50
- connection_factory.setClosedCallback { |_event| @on_close_cb.call }
51
- connection_factory.setExceptionHandler { |error| @on_error_cb.call(error) }
52
-
53
118
  # Setup ssl context if we're using tls
54
119
  if options[:uses_tls]
55
120
  ssl_context = create_ssl_context(options)
56
- connection_factory.setSecure(true)
57
- connection_factory.setSSLContext(ssl_context)
121
+ builder.sslContext(ssl_context)
58
122
  end
59
123
 
60
- @connection = connection_factory.createConnection
61
-
62
- # We're going to spawn a consumer and supervisor
63
- @work_queue = @connection.createMsgChannel
64
- spwan_supervisor_and_consumer
65
-
124
+ @connection = ::Java::IoNatsClient::Nats.connect(builder.build)
125
+ @dispatcher = @connection.createDispatcher(MessageHandlerProxy.empty)
66
126
  @connection
67
127
  end
68
128
 
@@ -75,64 +135,56 @@ module Protobuf
75
135
 
76
136
  # Do not depend on #close for a graceful disconnect.
77
137
  def close
78
- @connection.close rescue nil
138
+ if @connection
139
+ @connection.closeDispatcher(@dispatcher) rescue nil
140
+ @connection.close rescue nil
141
+ end
142
+ @dispatcher = nil
79
143
  @connection = nil
80
- @supervisor.kill rescue nil
81
- @supervisor = nil
82
- @consumer.kill rescue nil
83
- @supervisor = nil
84
144
  end
85
145
 
86
146
  def flush(timeout_sec = 0.5)
87
- connection.flush(timeout_sec * 1000)
147
+ duration = duration_in_ms(timeout_sec * 1000)
148
+ connection.flush(duration)
88
149
  end
89
150
 
90
151
  def next_message(sub, timeout_sec)
91
- nats_message = sub.nextMessage(timeout_sec * 1000)
152
+ duration = duration_in_ms(timeout_sec * 1000)
153
+ nats_message = sub.nextMessage(duration)
92
154
  return nil unless nats_message
93
155
  Message.new(nats_message)
94
156
  end
95
157
 
96
158
  def publish(subject, data, mailbox = nil)
97
159
  # The "true" here is to force flush. May not need this.
98
- connection.publish(subject, mailbox, data.to_java_bytes, true)
160
+ connection.publish(subject, mailbox, data.to_java_bytes)
161
+ connection.flush(nil)
99
162
  end
100
163
 
101
164
  def subscribe(subject, options = {}, &block)
102
165
  queue = options[:queue]
103
166
  max = options[:max]
104
- work_queue = nil
105
- # We pass our work queue for processing async work because java nats
106
- # uses a cahced thread pool: 1 thread per async subscription.
107
- # Sync subs need their own queue so work is not processed async.
108
- work_queue = block.nil? ? connection.createMsgChannel : @work_queue
109
- sub = connection.subscribe(subject, queue, nil, work_queue)
110
-
111
- # Register the block callback. We only lock to save the callback.
167
+
112
168
  if block
113
- @subz_mutex.synchronize do
114
- @subz_cbs[sub.getSid] = block
115
- end
169
+ handler = MessageHandlerProxy.new(&block)
170
+ sub = subscribe_using_subscription_dispatcher(subject, queue, handler)
171
+ # Auto unsub if max message option was provided.
172
+ dispatcher.unsubscribe(sub, max) if max
173
+ sub
174
+ else
175
+ sub = subscribe_using_connection(subject, queue)
176
+ sub.unsubscribe(max) if max
177
+ sub
116
178
  end
117
-
118
- # Auto unsub if max message option was provided.
119
- sub.autoUnsubscribe(max) if max
120
-
121
- sub
122
179
  end
123
180
 
124
181
  def unsubscribe(sub)
125
182
  return if sub.nil?
126
-
127
- # Cleanup our async callback
128
- if @subz_cbs[sub.getSid]
129
- @subz_mutex.synchronize do
130
- @subz_cbs.delete(sub.getSid)
131
- end
183
+ if sub.getDispatcher
184
+ dispatcher.unsubscribe(sub)
185
+ else
186
+ sub.unsubscribe()
132
187
  end
133
-
134
- # The "true" here is to ignore and invalid conn.
135
- sub.unsubscribe(true)
136
188
  end
137
189
 
138
190
  def new_inbox
@@ -140,69 +192,23 @@ module Protobuf
140
192
  end
141
193
 
142
194
  def on_reconnect(&cb)
143
- @on_reconnect_cb = cb
195
+ @connection_listener.on_reconnect(&cb)
144
196
  end
145
197
 
146
198
  def on_disconnect(&cb)
147
- @on_disconnect_cb = cb
199
+ @connection_listener.on_disconnect(&cb)
148
200
  end
149
201
 
150
202
  def on_error(&cb)
151
- @on_error_cb = cb
203
+ @error_listener.on_exception(&cb)
152
204
  end
153
205
 
154
206
  def on_close(&cb)
155
- @on_close_cb = cb
207
+ @connection_listener.on_close(&cb)
156
208
  end
157
209
 
158
210
  private
159
211
 
160
- def spwan_supervisor_and_consumer
161
- spawn_consumer
162
- @supervisor = ::Thread.new do
163
- loop do
164
- begin
165
- sleep 1
166
- next if @consumer && @consumer.alive?
167
- # We need to recreate the consumer thread
168
- @consumer.kill if @consumer
169
- spawn_consumer
170
- rescue => error
171
- @on_error_cb.call(error)
172
- end
173
- end
174
- end
175
- end
176
-
177
- def spawn_consumer
178
- @consumer = ::Thread.new do
179
- loop do
180
- begin
181
- message = @work_queue.take
182
- next unless message
183
- sub = message.getSubscription
184
-
185
- # We have to update the subscription stats so we're not considered a slow consumer.
186
- begin
187
- sub.lock
188
- sub.incrPMsgs(-1)
189
- sub.incrPBytes(-message.getData.length) if message.getData
190
- sub.incrDelivered(1) unless sub.isClosed
191
- ensure
192
- sub.unlock
193
- end
194
-
195
- # We don't need t
196
- callback = @subz_cbs[sub.getSid]
197
- next unless callback
198
- callback.call(message.getData.to_s, message.getReplyTo, message.getSubject)
199
- rescue => error
200
- @on_error_cb.call(error)
201
- end
202
- end
203
- end
204
- end
205
-
206
212
  # Jruby-openssl depends on bouncycastle so our lives don't suck super bad
207
213
  def read_pem_object_from_file(path)
208
214
  fail ::ArgumentError, "Tried to read a PEM key or cert with path nil" if path.nil?
@@ -246,6 +252,30 @@ module Protobuf
246
252
  context.init(key_manager.getKeyManagers, trust_manager.getTrustManagers, nil)
247
253
  context
248
254
  end
255
+
256
+ def duration_in_ms(ms)
257
+ ::Java::JavaTime::Duration.ofMillis(ms)
258
+ end
259
+
260
+ def subscribe_using_connection(subject, queue)
261
+ if queue
262
+ connection.subscribe(subject, queue)
263
+ else
264
+ connection.subscribe(subject)
265
+ end
266
+ end
267
+
268
+ def subscribe_using_subscription_dispatcher(subject, queue, handler)
269
+ if queue
270
+ dispatcher.java_send(:subscribe,
271
+ [::Java::JavaLang::String, ::Java::JavaLang::String, ::Java::IoNatsClient::MessageHandler],
272
+ subject, queue, handler)
273
+ else
274
+ dispatcher.java_send(:subscribe,
275
+ [::Java::JavaLang::String, ::Java::IoNatsClient::MessageHandler],
276
+ subject, handler)
277
+ end
278
+ end
249
279
  end
250
280
  end
251
281
  end
@@ -1,5 +1,5 @@
1
1
  module Protobuf
2
2
  module Nats
3
- VERSION = "0.10.5"
3
+ VERSION = "0.11.0.pre0"
4
4
  end
5
5
  end
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
11
11
 
12
12
  spec.summary = %q{ ruby-protobuf client/server for nats }
13
13
  spec.description = %q{ ruby-protobuf client/server for nats }
14
- spec.homepage = "https://github.com/mxenabled/protobuf-nats"
14
+ #spec.homepage = "TODO: Put your gem's website or public repo URL here."
15
15
  spec.license = "MIT"
16
16
 
17
17
  # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
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.10.5
4
+ version: 0.11.0.pre0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Dewitt
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-11-01 00:00:00.000000000 Z
11
+ date: 2019-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -171,7 +171,7 @@ files:
171
171
  - examples/warehouse/start_client.sh
172
172
  - examples/warehouse/start_server.sh
173
173
  - ext/jars/gson-2.6.2.jar
174
- - ext/jars/jnats-1.1-SNAPSHOT.jar
174
+ - ext/jars/jnats-2.6.0.jar
175
175
  - ext/jars/slf4j-api-1.7.25.jar
176
176
  - ext/jars/slf4j-simple-1.7.25.jar
177
177
  - lib/protobuf/nats.rb
@@ -184,13 +184,12 @@ files:
184
184
  - lib/protobuf/nats/thread_pool.rb
185
185
  - lib/protobuf/nats/version.rb
186
186
  - protobuf-nats.gemspec
187
- - scripts/install_gnatsd.sh
188
- homepage: https://github.com/mxenabled/protobuf-nats
187
+ homepage:
189
188
  licenses:
190
189
  - MIT
191
190
  metadata:
192
191
  allowed_push_host: https://rubygems.org
193
- post_install_message:
192
+ post_install_message:
194
193
  rdoc_options: []
195
194
  require_paths:
196
195
  - lib
@@ -201,12 +200,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
201
200
  version: '0'
202
201
  required_rubygems_version: !ruby/object:Gem::Requirement
203
202
  requirements:
204
- - - ">="
203
+ - - ">"
205
204
  - !ruby/object:Gem::Version
206
- version: '0'
205
+ version: 1.3.1
207
206
  requirements: []
208
- rubygems_version: 3.4.20
209
- signing_key:
207
+ rubyforge_project:
208
+ rubygems_version: 2.7.6
209
+ signing_key:
210
210
  specification_version: 4
211
211
  summary: ruby-protobuf client/server for nats
212
212
  test_files: []
Binary file
@@ -1,20 +0,0 @@
1
- #!/bin/bash
2
-
3
- set -e
4
-
5
- export DEFAULT_NATS_SERVER_VERSION=v2.0.0
6
-
7
- export NATS_SERVER_VERSION="${NATS_SERVER_VERSION:=$DEFAULT_NATS_SERVER_VERSION}"
8
-
9
- # check to see if nats-server folder is empty
10
- if [ ! "$(ls -A $HOME/nats-server)" ]; then
11
- (
12
- mkdir -p $HOME/nats-server
13
- cd $HOME/nats-server
14
- wget https://github.com/nats-io/nats-server/releases/download/$NATS_SERVER_VERSION/nats-server-$NATS_SERVER_VERSION-linux-amd64.zip -O nats-server.zip
15
- unzip nats-server.zip
16
- cp nats-server-$NATS_SERVER_VERSION-linux-amd64/nats-server $HOME/nats-server/nats-server
17
- )
18
- else
19
- echo 'Using cached directory.';
20
- fi