ffi-nats-core 0.2.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e8b2563b2cee5262ee5814315a9e6fc0a28ccc3a
4
+ data.tar.gz: 3cac7286f0393bc2eeaab9907b0807901663c361
5
+ SHA512:
6
+ metadata.gz: 5068c77e8ee41c18ae173fa25787279a34914da4d92ff3ad1e8f860da4377d4229087870b3ce8763c84fa0696246a6ed99596dc4f58418506cd1b33894413fb9
7
+ data.tar.gz: 447c4f636a5f790fee70d263fe1915e967a04fe31954b146bc911b2fc24de51713c3eaf00be8862dd436d305cfb8c6fa8b7ffa951f8e712b6c6cbbe9732bd35d
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ .ruby-*
2
+ /.bundle/
3
+ /.yardoc
4
+ /Gemfile.lock
5
+ /_yardoc/
6
+ /coverage/
7
+ /doc/
8
+ /pkg/
9
+ /spec/reports/
10
+ /tmp/
11
+ ext/libnats.so
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.0
5
+ before_install: gem install bundler -v 1.13.6
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ffi-nats-core.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,36 @@
1
+ # FFI::Nats::Core
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/ffi/nats/core`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'ffi-nats-core'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install ffi-nats-core
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ 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).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/ffi-nats-core.
36
+
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :test
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "ffi/nats/core"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ffi/nats/core/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ffi-nats-core"
8
+ spec.version = FFI::Nats::Core::VERSION
9
+ spec.authors = ["Brandon Dewitt"]
10
+ spec.email = ["brandonsdewitt@gmail.com"]
11
+
12
+ spec.summary = %q{ core ffi bindings for ffi-nats }
13
+ spec.description = %q{ core ffi bindings for ffi-nats }
14
+ spec.homepage = "https://www.github.com/abrandoned/ffi-nats-core"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_dependency "ffi"
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.13"
26
+ spec.add_development_dependency "pry"
27
+ spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency "minitest", "~> 5.0"
29
+ end
@@ -0,0 +1,7 @@
1
+ module FFI
2
+ module Nats
3
+ module Core
4
+ VERSION = "0.2.1"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,464 @@
1
+ require "ffi/nats/core/version"
2
+ require 'rubygems'
3
+ require 'ffi'
4
+ require 'thread'
5
+ require 'securerandom'
6
+
7
+ #trap(:TRAP) do
8
+ # ::Thread.list.each do |thread|
9
+ # $stdout << <<-THREAD_TRACE
10
+ # #{thread.inspect}:
11
+ # #{thread.backtrace && thread.backtrace.join($INPUT_RECORD_SEPARATOR)}"
12
+ # THREAD_TRACE
13
+ # end
14
+ #end
15
+
16
+ module FFI
17
+ module Nats
18
+ module Core
19
+ extend FFI::Library
20
+ ffi_lib_flags :now, :global
21
+
22
+ ##
23
+ # ffi-rzmq-core for reference
24
+ #
25
+ # https://github.com/chuckremes/ffi-rzmq-core/blob/master/lib/ffi-rzmq-core/libzmq.rb
26
+ #
27
+ begin
28
+ # bias the library discovery to a path inside the gem first, then
29
+ # to the usual system paths
30
+ inside_gem = File.join(File.dirname(__FILE__), '..', '..', '..', 'ext')
31
+ local_path = FFI::Platform::IS_WINDOWS ? ENV['PATH'].split(';') : ENV['PATH'].split(':')
32
+ env_path = [ ENV['NATS_LIB_PATH'] ].compact
33
+ rbconfig_path = RbConfig::CONFIG["libdir"]
34
+ homebrew_path = nil
35
+
36
+ # RUBYOPT set by RVM breaks 'brew' so we need to unset it.
37
+ rubyopt = ENV.delete('RUBYOPT')
38
+
39
+ begin
40
+ stdout, stderr, status = Open3.capture3("brew", "--prefix")
41
+ homebrew_path = if status.success?
42
+ "#{stdout.chomp}/lib"
43
+ else
44
+ '/usr/local/homebrew/lib'
45
+ end
46
+ rescue
47
+ # Homebrew doesn't exist
48
+ end
49
+
50
+ # Restore RUBYOPT after executing 'brew' above.
51
+ ENV['RUBYOPT'] = rubyopt
52
+
53
+ # Search for libnats in the following order...
54
+ NATS_LIB_PATHS = ([inside_gem] + env_path + local_path + [rbconfig_path] + [
55
+ '/usr/local/lib', '/opt/local/lib', homebrew_path, '/usr/lib64'
56
+ ]).compact.map{|path| "#{path}/libnats.#{FFI::Platform::LIBSUFFIX}"}
57
+ ffi_lib(NATS_LIB_PATHS + %w{libnats})
58
+
59
+ rescue LoadError
60
+ if NATS_LIB_PATHS.any? {|path|
61
+ File.file? File.join(path, "libnats.#{FFI::Platform::LIBSUFFIX}")}
62
+ warn "Unable to load this gem. The libnats library exists, but cannot be loaded."
63
+ warn "Set NATS_LIB_PATH if custom load path is desired"
64
+ warn "If this is Windows:"
65
+ warn "- Check that you have MSVC runtime installed or statically linked"
66
+ warn "- Check that your DLL is compiled for #{FFI::Platform::ADDRESS_SIZE} bit"
67
+ else
68
+ warn "Unable to load this gem. The libnats library (or DLL) could not be found."
69
+ warn "Set NATS_LIB_PATH if custom load path is desired"
70
+ warn "If this is a Windows platform, make sure libnats.dll is on the PATH."
71
+ warn "If the DLL was built with mingw, make sure the other two dependent DLLs,"
72
+ warn "libgcc_s_sjlj-1.dll and libstdc++6.dll, are also on the PATH."
73
+ warn "For non-Windows platforms, make sure libnats is located in this search path:"
74
+ warn NATS_LIB_PATHS.inspect
75
+ end
76
+ raise LoadError, "The libnats library (or DLL) could not be loaded"
77
+ end
78
+
79
+ enum :NATS_CONN_STATUS, [
80
+ :DISCONNECTED, 0, #///< The connection has been disconnected
81
+ :CONNECTING, #///< The connection is in the process or connecting
82
+ :CONNECTED, #///< The connection is connected
83
+ :CLOSED, #///< The connection is closed
84
+ :RECONNECTING #///< The connection is in the process or reconnecting
85
+ ]
86
+
87
+ NATS_STATUS = enum [
88
+ :NATS_OK, 0, #< Success
89
+ :NATS_ERR, #< Generic error
90
+ :NATS_PROTOCOL_ERROR, #< Error when parsing a protocol message, or not getting the expected message.
91
+ :NATS_IO_ERROR, #< IO Error (network communication).
92
+ :NATS_LINE_TOO_LONG, #< The protocol message read from the socket does not fit in the read buffer.
93
+ :NATS_CONNECTION_CLOSED, #< Operation on this connection failed because the connection is closed.
94
+ :NATS_NO_SERVER, #< Unable to connect, the server could not be reached or is not running.
95
+ :NATS_STALE_CONNECTION, #< The server closed our connection because it did not receive PINGs at the expected interval.
96
+ :NATS_SECURE_CONNECTION_WANTED, #< The client is configured to use TLS, but the server is not.
97
+ :NATS_SECURE_CONNECTION_REQUIRED,#< The server expects a TLS connection.
98
+ :NATS_CONNECTION_DISCONNECTED, #< The connection was disconnected. Depending on the configuration, the connection may reconnect.
99
+ :NATS_CONNECTION_AUTH_FAILED, #< The connection failed due to authentication error.
100
+ :NATS_NOT_PERMITTED, #< The action is not permitted.
101
+ :NATS_NOT_FOUND, #< An action could not complete because something was not found. So far, this is an internal error.
102
+ :NATS_ADDRESS_MISSING, #< Incorrect URL. For instance no host specified in the URL.
103
+ :NATS_INVALID_SUBJECT, #< Invalid subject, for instance NULL or empty string.
104
+ :NATS_INVALID_ARG, #< An invalid argument is passed to a function. For instance passing NULL to an API that does not accept this value.
105
+ :NATS_INVALID_SUBSCRIPTION, #< The call to a subscription function fails because the subscription has previously been closed.
106
+ :NATS_INVALID_TIMEOUT, #< Timeout must be positive numbers.
107
+ :NATS_ILLEGAL_STATE, #< An unexpected state, for instance calling #natsSubscription_NextMsg() on an asynchronous subscriber.
108
+ :NATS_SLOW_CONSUMER, #< The maximum number of messages waiting to be delivered has been reached. Messages are dropped.
109
+ :NATS_MAX_PAYLOAD, #< Attempt to send a payload larger than the maximum allowed by the NATS Server.
110
+ :NATS_MAX_DELIVERED_MSGS, #< Attempt to receive more messages than allowed, for instance because of #natsSubscription_AutoUnsubscribe().
111
+ :NATS_INSUFFICIENT_BUFFER, #< A buffer is not large enough to accommodate the data.
112
+ :NATS_NO_MEMORY, #< An operation could not complete because of insufficient memory.
113
+ :NATS_SYS_ERROR, #< Some system function returned an error.
114
+ :NATS_TIMEOUT, #< An operation timed-out. For instance #natsSubscription_NextMsg().
115
+ :NATS_FAILED_TO_INITIALIZE, #< The library failed to initialize.
116
+ :NATS_NOT_INITIALIZED, #< The library is not yet initialized.
117
+ :NATS_SSL_ERROR #< An SSL error occurred when trying to establish a connection.
118
+ ]
119
+
120
+ # message handler callback definition
121
+ callback :on_message_function, [:pointer, :pointer, :pointer, :pointer], :void
122
+ callback :on_error_function, [:pointer, :pointer, :int, :pointer], :void
123
+ callback :on_connected_function, [:pointer, :pointer], :void
124
+
125
+ # nats
126
+ attach_function :nats_Close, [], :void, :blocking => true
127
+ attach_function :nats_GetLastError, [:pointer], :strptr, :blocking => true
128
+ attach_function :nats_GetLastErrorStack, [:buffer_out, :size_t], :int, :blocking => true
129
+ attach_function :nats_GetVersion, [], :strptr, :blocking => true
130
+ attach_function :nats_GetVersionNumber, [], :uint32, :blocking => true
131
+ attach_function :nats_Now, [], :int64, :blocking => true
132
+ attach_function :nats_NowInNanoSeconds, [], :int64, :blocking => true
133
+ attach_function :nats_Open, [:int64], :int, :blocking => true
134
+ # attach_function :nats_PrintLastErrorStack, [:pointer], :void
135
+ attach_function :nats_SetMessageDeliveryPoolSize, [:int], :int, :blocking => true
136
+ attach_function :nats_Sleep, [:int64], :void, :blocking => true
137
+
138
+ # natsConnection
139
+ attach_function :natsConnection_Buffered, [:pointer], :int, :blocking => true
140
+ attach_function :natsConnection_Close, [:pointer], :void, :blocking => true
141
+ attach_function :natsConnection_Connect, [:pointer, :pointer], :int, :blocking => true
142
+ attach_function :natsConnection_ConnectTo, [:pointer, :string], :int, :blocking => true
143
+ attach_function :natsConnection_Destroy, [:pointer], :void, :blocking => true
144
+ attach_function :natsConnection_Flush, [:pointer], :int, :blocking => true
145
+ attach_function :natsConnection_FlushTimeout, [:pointer, :int], :int, :blocking => true
146
+ attach_function :natsConnection_GetConnectedServerId, [:pointer, :buffer_out, :size_t], :int, :blocking => true
147
+ attach_function :natsConnection_GetConnectedUrl, [:pointer, :buffer_out, :size_t], :int, :blocking => true
148
+ attach_function :natsConnection_GetLastError, [:pointer, :pointer], :int, :blocking => true
149
+ attach_function :natsConnection_GetMaxPayload, [:pointer], :int64, :blocking => true
150
+ attach_function :natsConnection_GetStats, [:pointer, :pointer], :int, :blocking => true
151
+ attach_function :natsConnection_IsClosed, [:pointer], :bool, :blocking => true
152
+ attach_function :natsConnection_IsReconnecting, [:pointer], :bool, :blocking => true
153
+ attach_function :natsConnection_Publish, [:pointer, :string, :pointer, :int], :int, :blocking => true
154
+ attach_function :natsConnection_PublishMsg, [:pointer, :pointer], :int, :blocking => true
155
+ attach_function :natsConnection_PublishRequest, [:pointer, :string, :string, :pointer, :int], :int, :blocking => true
156
+ attach_function :natsConnection_PublishRequestString, [:pointer, :string, :string, :string], :int, :blocking => true
157
+ attach_function :natsConnection_PublishString, [:pointer, :string, :string], :int, :blocking => true
158
+ attach_function :natsConnection_Request, [:pointer, :pointer, :string, :pointer, :int, :int64], :int, :blocking => true
159
+ attach_function :natsConnection_RequestString, [:pointer, :pointer, :string, :string, :int64], :int, :blocking => true
160
+ attach_function :natsConnection_Status, [:pointer], :int, :blocking => true
161
+ attach_function :natsConnection_Subscribe, [:pointer, :pointer, :string, :on_message_function, :pointer], :int, :blocking => true
162
+ attach_function :natsConnection_SubscribeSync, [:pointer, :pointer, :string], :int, :blocking => true
163
+ attach_function :natsConnection_SubscribeTimeout, [:pointer, :pointer, :string, :int64, :on_message_function, :pointer], :int, :blocking => true
164
+ attach_function :natsConnection_QueueSubscribe, [:pointer, :pointer, :string, :string, :on_message_function, :pointer], :int, :blocking => true
165
+ attach_function :natsConnection_QueueSubscribeSync, [:pointer, :pointer, :string, :string], :int, :blocking => true
166
+ attach_function :natsConnection_QueueSubscribeTimeout, [:pointer, :pointer, :string, :string, :int64, :on_message_function, :pointer], :int, :blocking => true
167
+
168
+ # natsInbox
169
+ attach_function :natsInbox_Create, [:pointer], :int, :blocking => true
170
+ attach_function :natsInbox_Destroy, [:pointer], :void, :blocking => true
171
+
172
+ # natsMsg
173
+ attach_function :natsMsg_Create, [:pointer, :string, :string, :string, :int], :int, :blocking => true
174
+ attach_function :natsMsg_Destroy, [:pointer], :void, :blocking => true
175
+ attach_function :natsMsg_GetSubject, [:pointer], :strptr, :blocking => true
176
+ attach_function :natsMsg_GetReply, [:pointer], :strptr, :blocking => true
177
+ attach_function :natsMsg_GetData, [:pointer], :strptr, :blocking => true
178
+ attach_function :natsMsg_GetDataLength, [:pointer], :int, :blocking => true
179
+
180
+ # natsNUID
181
+ attach_function :natsNUID_free, [], :void, :blocking => true
182
+ attach_function :natsNUID_init, [], :void, :blocking => true
183
+ attach_function :natsNUID_Next, [:string, :int], :void, :blocking => true
184
+
185
+ # natsOptions
186
+ attach_function :natsOptions_Create, [:pointer], :int, :blocking => true
187
+ attach_function :natsOptions_Destroy, [:pointer], :void, :blocking => true
188
+ attach_function :natsOptions_IPResolutionOrder, [:pointer, :int], :int, :blocking => true
189
+ attach_function :natsOptions_LoadCATrustedCertificates, [:pointer, :string], :int, :blocking => true
190
+ attach_function :natsOptions_LoadCertificatesChain, [:pointer, :string, :string], :int, :blocking => true
191
+ attach_function :natsOptions_SetAllowReconnect, [:pointer, :bool], :int, :blocking => true
192
+ attach_function :natsOptions_SetCiphers, [:pointer, :string], :int, :blocking => true
193
+ attach_function :natsOptions_SetExpectedHostname, [:pointer, :string], :int, :blocking => true
194
+ attach_function :natsOptions_SetErrorHandler, [:pointer, :on_error_function, :pointer], :int, :blocking => true
195
+ attach_function :natsOptions_SetDisconnectedCB, [:pointer, :on_connected_function, :pointer], :int, :blocking => true
196
+ attach_function :natsOptions_SetReconnectedCB, [:pointer, :on_connected_function, :pointer], :int, :blocking => true
197
+ attach_function :natsOptions_SetMaxPingsOut, [:pointer, :int64], :int, :blocking => true
198
+ attach_function :natsOptions_SetMaxPendingMsgs, [:pointer, :int], :int, :blocking => true
199
+ attach_function :natsOptions_SetMaxReconnect, [:pointer, :int], :int, :blocking => true
200
+ attach_function :natsOptions_SetReconnectBufSize, [:pointer, :int], :int, :blocking => true
201
+ attach_function :natsOptions_SetReconnectWait, [:pointer, :int64], :int, :blocking => true
202
+ attach_function :natsOptions_SetName, [:pointer, :string], :int, :blocking => true
203
+ attach_function :natsOptions_SetNoRandomize, [:pointer, :bool], :int, :blocking => true
204
+ attach_function :natsOptions_SetPedantic, [:pointer, :bool], :int, :blocking => true
205
+ attach_function :natsOptions_SetPingInterval, [:pointer, :int64], :int, :blocking => true
206
+ attach_function :natsOptions_SetSecure, [:pointer, :bool], :int, :blocking => true
207
+ attach_function :natsOptions_SetServers, [:pointer, :pointer, :int], :int, :blocking => true
208
+ attach_function :natsOptions_SetTimeout, [:pointer, :int64], :int, :blocking => true
209
+ attach_function :natsOptions_SetToken, [:pointer, :string], :int, :blocking => true
210
+ attach_function :natsOptions_SetURL, [:pointer, :string], :int, :blocking => true
211
+ attach_function :natsOptions_SetUserInfo, [:pointer, :string, :string], :int, :blocking => true
212
+ attach_function :natsOptions_SetVerbose, [:pointer, :bool], :int, :blocking => true
213
+ attach_function :natsOptions_UseGlobalMessageDelivery, [:pointer, :bool], :int, :blocking => true
214
+
215
+ # natsSubscription
216
+ attach_function :natsSubscription_AutoUnsubscribe, [:pointer, :int], :int, :blocking => true
217
+ attach_function :natsSubscription_ClearMaxPending, [:pointer], :int, :blocking => true
218
+ attach_function :natsSubscription_Destroy, [:pointer], :void, :blocking => true
219
+ attach_function :natsSubscription_GetDelivered, [:pointer, :pointer], :int, :blocking => true
220
+ attach_function :natsSubscription_GetDropped, [:pointer, :pointer], :int, :blocking => true
221
+ attach_function :natsSubscription_GetMaxPending, [:pointer, :pointer, :pointer], :int, :blocking => true
222
+ attach_function :natsSubscription_GetPending, [:pointer, :pointer, :pointer], :int, :blocking => true
223
+ attach_function :natsSubscription_GetPendingLimits, [:pointer, :pointer, :pointer], :int, :blocking => true
224
+ attach_function :natsSubscription_GetStats, [:pointer, :pointer, :pointer, :pointer, :pointer, :pointer, :pointer], :int, :blocking => true
225
+ attach_function :natsSubscription_IsValid, [:pointer], :bool, :blocking => true
226
+ attach_function :natsSubscription_NextMsg, [:pointer, :pointer, :int64], :int, :blocking => true
227
+ attach_function :natsSubscription_NoDeliveryDelay, [:pointer], :int, :blocking => true
228
+ attach_function :natsSubscription_SetPendingLimits, [:pointer, :int, :int], :int, :blocking => true
229
+ attach_function :natsSubscription_Unsubscribe, [:pointer], :int, :blocking => true
230
+
231
+ # natsStatistics
232
+ attach_function :natsStatistics_Create, [:pointer], :int, :blocking => true
233
+ attach_function :natsStatistics_Destroy, [:pointer], :void, :blocking => true
234
+ attach_function :natsStatistics_GetCounts, [:pointer, :pointer, :pointer, :pointer, :pointer, :pointer], :int, :blocking => true
235
+
236
+ # natsStatus
237
+ attach_function :natsStatus_GetText, [NATS_STATUS], :strptr, :blocking => true
238
+
239
+
240
+ SubscribeCallback = FFI::Function.new(:void, [:pointer, :pointer, :pointer, :pointer], :blocking => true) do |conn, sub, msg, closure|
241
+ #queue_name = closure.read_string
242
+ #queue_name = FFI::Nats::Core.natsMsg_GetSubject(msg)
243
+ #queue_for_and_remove(queue_name) << FFI::Nats::Core.natsMsg_GetData(msg)
244
+
245
+ #print "+"
246
+ reply_to, _ = FFI::Nats::Core.natsMsg_GetReply(msg)
247
+ FFI::Nats::Core.natsConnection_PublishString(conn, reply_to, "thanks")
248
+ FFI::Nats::Core.natsConnection_Flush(conn)
249
+ FFI::Nats::Core.natsMsg_Destroy(msg)
250
+ end
251
+
252
+ def self.subscribe(connection, subscription, subject, &blk)
253
+ if blk.arity == 4
254
+ FFI::Nats::Core.natsConnection_Subscribe(subscription, connection, subject, blk, nil)
255
+ else
256
+ raise "subscribe block arity must be 4 ... ish"
257
+ end
258
+ end
259
+
260
+ def self.run_subscribe(connection)
261
+ subscription = FFI::MemoryPointer.new :pointer
262
+ uuid = SecureRandom.uuid
263
+ q = Queue.new
264
+ #q = queue_for(uuid)
265
+
266
+ #FFI::Nats::Core.natsConnection_Subscribe(subscription, connection, uuid, FFI::Nats::Core::SubscribeCallback, nil)
267
+ subscribe(connection, subscription, uuid) do |conn, sub, msg, closure|
268
+ print "+"
269
+ data, _ = FFI::Nats::Core.natsMsg_GetData(msg)
270
+ subject, _ = FFI::Nats::Core.natsMsg_GetSubject(msg)
271
+ q << data
272
+ FFI::Nats::Core.natsMsg_Destroy(msg)
273
+ FFI::Nats::Core.natsSubscription_Unsubscribe(sub)
274
+ end
275
+
276
+ #FFI::Nats::Core.natsSubscription_AutoUnsubscribe(subscription.get_pointer(0), 1)
277
+ sub = subscription.get_pointer(0)
278
+ #FFI::Nats::Core.natsSubscription_AutoUnsubscribe(sub, 1)
279
+ FFI::Nats::Core.natsConnection_PublishString(connection, uuid, "hello from the other side")
280
+ #FFI::Nats::Core.natsConnection_Flush(connection)
281
+
282
+ q.pop
283
+ FFI::Nats::Core.natsSubscription_Destroy(sub)
284
+ end
285
+
286
+ def self.test_subscribe
287
+ threads = []
288
+
289
+ 1.times do
290
+ threads << Thread.new do
291
+ connection_pointer = FFI::MemoryPointer.new :pointer
292
+ FFI::Nats::Core.natsConnection_ConnectTo(connection_pointer, "nats://localhost:4222")
293
+ connection = connection_pointer.get_pointer(0)
294
+
295
+ 1_000.times do
296
+ run_subscribe(connection)
297
+ end
298
+
299
+ FFI::Nats::Core.natsConnection_Flush(connection)
300
+ FFI::Nats::Core.natsConnection_Close(connection)
301
+ FFI::Nats::Core.natsConnection_Destroy(connection)
302
+ end
303
+ end
304
+
305
+ threads.map(&:join)
306
+ end
307
+
308
+ def self.test_request_reply
309
+ start = Time.now
310
+ num_threads = 8
311
+ publish_per_thread = 100_000
312
+ threads = []
313
+ subject = "hello"
314
+ message = "world"
315
+ reply = "thanks"
316
+ message_size = message.size
317
+
318
+ subscription = FFI::MemoryPointer.new :pointer
319
+ opts_pointer = FFI::MemoryPointer.new :pointer
320
+ conn_t = FFI::MemoryPointer.new :pointer
321
+
322
+ FFI::Nats::Core.natsOptions_Create(opts_pointer)
323
+ opts_pointer = opts_pointer.get_pointer(0)
324
+ FFI::Nats::Core.natsOptions_SetURL(opts_pointer, "nats://localhost:4222")
325
+ FFI::Nats::Core.natsOptions_UseGlobalMessageDelivery(opts_pointer, true)
326
+
327
+ FFI::Nats::Core.natsConnection_Connect(conn_t, opts_pointer)
328
+ conn_t = conn_t.get_pointer(0)
329
+ FFI::Nats::Core.natsConnection_Subscribe(subscription, conn_t, subject, FFI::Nats::Core::SubscribeCallback, nil)
330
+ FFI::Nats::Core.natsConnection_Flush(conn_t)
331
+
332
+ num_threads.times do
333
+ threads << Thread.new do
334
+ options_pointer = FFI::MemoryPointer.new :pointer
335
+ connection_pointer = FFI::MemoryPointer.new :pointer
336
+
337
+ FFI::Nats::Core.natsOptions_Create(options_pointer)
338
+ options_pointer = options_pointer.get_pointer(0)
339
+ FFI::Nats::Core.natsOptions_SetURL(options_pointer, "nats://localhost:4222")
340
+
341
+ FFI::Nats::Core.natsConnection_Connect(connection_pointer, options_pointer)
342
+ connection_pointer = connection_pointer.get_pointer(0)
343
+
344
+ publish_per_thread.times do
345
+ FFI::MemoryPointer.new(:pointer) do |message_pointer|
346
+ FFI::Nats::Core.natsConnection_RequestString(message_pointer, connection_pointer, subject, message, 1000)
347
+ FFI::Nats::Core.natsMsg_Destroy(message_pointer.get_pointer(0))
348
+ end
349
+ end
350
+ end
351
+ end
352
+
353
+ threads.map(&:join)
354
+
355
+ FFI::Nats::Core.natsSubscription_Unsubscribe(subscription.get_pointer(0))
356
+ FFI::Nats::Core.natsSubscription_Destroy(subscription.get_pointer(0))
357
+
358
+ finish = Time.now
359
+ time_diff = finish.to_i - start.to_i
360
+ throughput = (num_threads * publish_per_thread)
361
+ puts <<-FINISH
362
+ THREADS: #{num_threads}
363
+ PUBLISH PER THREAD: #{publish_per_thread}
364
+ START: #{start}
365
+ FINISH: #{finish}
366
+ PER SECOND: #{time_diff == 0 ? throughput : throughput/time_diff}
367
+ FINISH
368
+ end
369
+
370
+ def self.test_threaded_single_connection
371
+ start = Time.now
372
+ num_threads = 8
373
+ publish_per_thread = 500_000
374
+ publishes = 0
375
+ threads = []
376
+ subject = "hello"
377
+ message = "world"
378
+ message_size = message.size
379
+
380
+ options_pointer = FFI::MemoryPointer.new :pointer
381
+ connection_pointer = FFI::MemoryPointer.new :pointer
382
+
383
+ FFI::Nats::Core.natsOptions_Create(options_pointer)
384
+ options_pointer = options_pointer.get_pointer(0)
385
+ FFI::Nats::Core.natsOptions_SetURL(options_pointer, "nats://0.0.0.0:4222")
386
+
387
+ FFI::Nats::Core.natsConnection_Connect(connection_pointer, options_pointer)
388
+ connection_pointer = connection_pointer.get_pointer(0)
389
+
390
+ num_threads.times do
391
+ threads << Thread.new do
392
+ publish_per_thread.times do
393
+ status = FFI::Nats::Core.natsConnection_Publish(connection_pointer, subject, message, message.size)
394
+ puts status unless NATS_STATUS[status] == NATS_STATUS[:NATS_OK]
395
+ end
396
+ end
397
+ end
398
+
399
+ threads.map(&:join)
400
+ FFI::Nats::Core.natsConnection_Flush(connection_pointer)
401
+ finish = Time.now
402
+ total_time = finish.to_i - start.to_i
403
+ total_time = 1 if total_time.zero?
404
+ puts <<-FINISH
405
+ PUBLISHES: #{publishes}
406
+ THREADS: #{num_threads}
407
+ PUBLISH PER THREAD: #{publish_per_thread}
408
+ START: #{start}
409
+ FINISH: #{finish}
410
+ PER SECOND: #{(num_threads * publish_per_thread)/total_time}
411
+ FINISH
412
+ end
413
+
414
+ def self.test_threaded
415
+ start = Time.now
416
+ num_threads = 4
417
+ publish_per_thread = 100_000
418
+ threads = []
419
+ subject = "hello"
420
+ message = "world"
421
+ message_size = message.size
422
+
423
+ num_threads.times do
424
+ threads << Thread.new do
425
+ connection_pointer = nil
426
+
427
+ if false
428
+ connection_pointer = FFI::MemoryPointer.new :pointer
429
+ FFI::Nats::Core.natsConnection_ConnectTo(connection_pointer, "nats://localhost:4222")
430
+ connection_pointer = connection_pointer.get_pointer(0)
431
+ else
432
+ options_pointer = FFI::MemoryPointer.new :pointer
433
+ connection_pointer = FFI::MemoryPointer.new :pointer
434
+
435
+ FFI::Nats::Core.natsOptions_Create(options_pointer)
436
+ options_pointer = options_pointer.get_pointer(0)
437
+ FFI::Nats::Core.natsOptions_SetURL(options_pointer, "nats://0.0.0.0:4222")
438
+
439
+ FFI::Nats::Core.natsConnection_Connect(connection_pointer, options_pointer)
440
+ connection_pointer = connection_pointer.get_pointer(0)
441
+ end
442
+
443
+ publish_per_thread.times do
444
+ FFI::Nats::Core.natsConnection_PublishString(connection_pointer, subject, message)
445
+ end
446
+ end
447
+ end
448
+
449
+ threads.map(&:join)
450
+ finish = Time.now
451
+ total_time = finish.to_i - start.to_i
452
+ total_time = 1 if total_time.zero?
453
+ puts <<-FINISH
454
+ THREADS: #{num_threads}
455
+ PUBLISH PER THREAD: #{publish_per_thread}
456
+ START: #{start}
457
+ FINISH: #{finish}
458
+ PER SECOND: #{(num_threads * publish_per_thread)/total_time}
459
+ FINISH
460
+ end
461
+
462
+ end
463
+ end
464
+ end
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ffi-nats-core
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.1
5
+ platform: ruby
6
+ authors:
7
+ - Brandon Dewitt
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-04-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ffi
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.13'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.13'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '5.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '5.0'
83
+ description: " core ffi bindings for ffi-nats "
84
+ email:
85
+ - brandonsdewitt@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".travis.yml"
92
+ - Gemfile
93
+ - README.md
94
+ - Rakefile
95
+ - bin/console
96
+ - bin/setup
97
+ - ffi-nats-core.gemspec
98
+ - lib/ffi/nats/core.rb
99
+ - lib/ffi/nats/core/version.rb
100
+ homepage: https://www.github.com/abrandoned/ffi-nats-core
101
+ licenses: []
102
+ metadata: {}
103
+ post_install_message:
104
+ rdoc_options: []
105
+ require_paths:
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ requirements: []
118
+ rubyforge_project:
119
+ rubygems_version: 2.5.2
120
+ signing_key:
121
+ specification_version: 4
122
+ summary: core ffi bindings for ffi-nats
123
+ test_files: []