ffi-nats-core 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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: []