cztop 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +31 -0
  5. data/.yardopts +1 -0
  6. data/AUTHORS +1 -0
  7. data/CHANGES.md +3 -0
  8. data/Gemfile +10 -0
  9. data/Guardfile +61 -0
  10. data/LICENSE +5 -0
  11. data/Procfile +3 -0
  12. data/README.md +408 -0
  13. data/Rakefile +6 -0
  14. data/bin/console +7 -0
  15. data/bin/setup +7 -0
  16. data/ci-scripts/install-deps +9 -0
  17. data/cztop.gemspec +36 -0
  18. data/examples/ruby_actor/actor.rb +100 -0
  19. data/examples/simple_req_rep/rep.rb +12 -0
  20. data/examples/simple_req_rep/req.rb +35 -0
  21. data/examples/taxi_system/.gitignore +2 -0
  22. data/examples/taxi_system/Makefile +2 -0
  23. data/examples/taxi_system/README.gsl +115 -0
  24. data/examples/taxi_system/README.md +276 -0
  25. data/examples/taxi_system/broker.rb +98 -0
  26. data/examples/taxi_system/client.rb +34 -0
  27. data/examples/taxi_system/generate_keys.rb +24 -0
  28. data/examples/taxi_system/start_broker.sh +2 -0
  29. data/examples/taxi_system/start_clients.sh +11 -0
  30. data/lib/cztop/actor.rb +308 -0
  31. data/lib/cztop/authenticator.rb +97 -0
  32. data/lib/cztop/beacon.rb +96 -0
  33. data/lib/cztop/certificate.rb +176 -0
  34. data/lib/cztop/config/comments.rb +66 -0
  35. data/lib/cztop/config/serialization.rb +82 -0
  36. data/lib/cztop/config/traversing.rb +157 -0
  37. data/lib/cztop/config.rb +119 -0
  38. data/lib/cztop/frame.rb +158 -0
  39. data/lib/cztop/has_ffi_delegate.rb +85 -0
  40. data/lib/cztop/message/frames.rb +74 -0
  41. data/lib/cztop/message.rb +191 -0
  42. data/lib/cztop/monitor.rb +102 -0
  43. data/lib/cztop/poller.rb +334 -0
  44. data/lib/cztop/polymorphic_zsock_methods.rb +24 -0
  45. data/lib/cztop/proxy.rb +149 -0
  46. data/lib/cztop/send_receive_methods.rb +35 -0
  47. data/lib/cztop/socket/types.rb +207 -0
  48. data/lib/cztop/socket.rb +106 -0
  49. data/lib/cztop/version.rb +3 -0
  50. data/lib/cztop/z85.rb +157 -0
  51. data/lib/cztop/zsock_options.rb +334 -0
  52. data/lib/cztop.rb +55 -0
  53. data/perf/README.md +79 -0
  54. data/perf/inproc_lat.rb +49 -0
  55. data/perf/inproc_thru.rb +42 -0
  56. data/perf/local_lat.rb +35 -0
  57. data/perf/remote_lat.rb +26 -0
  58. metadata +297 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: eb0ba59995fcb10d5dd7054d72ba49cf886281ea
4
+ data.tar.gz: deea479538b525d5f92673bd694b8d34f5b8e7d8
5
+ SHA512:
6
+ metadata.gz: 1849347983836cf93974f9f51d41147a1cacd6e4950b77b8ebac2a62429827b58fff40e8de41fe6c16cc44c8663c4009b8e20f44fe74c00956047885ccc21a73
7
+ data.tar.gz: e278d6d22d69c2e0f83bbaaed62057be6883a175749eee567aafd8343fde586cf3cb812c5e8e75e56ad56ec6808abd4617a907dc11f4ce06e5f1091fd167e4f7
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /*.vimsession
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,31 @@
1
+ language: ruby
2
+ sudo: false
3
+ cache:
4
+ directories:
5
+ - $HOME/.ccache
6
+ - $HOME/.bundle
7
+ rvm:
8
+ - 2.3.0
9
+ - 2.2.4
10
+ - 2.1.8
11
+ - jruby-head
12
+ - rbx
13
+ env:
14
+ # recognized by czmq-ffi-gen's ci-scripts
15
+ - CZMQ_VERSION=HEAD ZMQ_VERSION=HEAD
16
+ - CZMQ_VERSION=3.0 ZMQ_VERSION=4.1
17
+ matrix:
18
+ exclude:
19
+ # old ruby versions don't get to test bleeding edge functionality. basta.
20
+ - rvm: 2.2.4
21
+ env: CZMQ_VERSION=HEAD ZMQ_VERSION=HEAD
22
+ - rvm: 2.1.8
23
+ env: CZMQ_VERSION=HEAD ZMQ_VERSION=HEAD
24
+ before_install:
25
+ - PATH="/usr/lib/ccache:$PATH" # enable ccache
26
+ - export LD_LIBRARY_PATH=$HOME/lib # custom libs (for execution)
27
+ - export PKG_CONFIG_PATH=$HOME/lib/pkgconfig # custom libs (for linking)
28
+ - export BUNDLE_PATH=$HOME/.bundle # bundle caching
29
+ - ci-scripts/install-deps
30
+ - gem install bundler -v 1.10.6
31
+ script: bundle exec rake spec
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --private lib/**/*.rb - README.md LICENSE
data/AUTHORS ADDED
@@ -0,0 +1 @@
1
+ Patrik Wenger <paddor@gmail.com>
data/CHANGES.md ADDED
@@ -0,0 +1,3 @@
1
+ 0.1.0 (23/01/2016)
2
+ -----
3
+ * first release
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+
4
+ # useful when working on czmq-ffi-gen in parallel
5
+ #gem "czmq-ffi-gen", git: "https://github.com/paddor/czmq-ffi-gen.git"
6
+
7
+ group :development do
8
+ gem 'rubocop', require: false
9
+ gem 'coveralls', require: false, platform: :mri
10
+ end
data/Guardfile ADDED
@@ -0,0 +1,61 @@
1
+ require "guard/rspec/dsl"
2
+
3
+ # Start using
4
+ #
5
+ # bundle exec guard -g doc & bundle exec guard -g spec
6
+ #
7
+ # This way you get parallel execution, so
8
+ # * documentation is regenerated immediately
9
+ # * specs are run immediately
10
+
11
+ README_FILE = %r{^README\.md}
12
+
13
+ # set these later using help from guard-rspec
14
+ ruby_lib_files = nil
15
+ spec_files = nil
16
+
17
+ # I don't need no shell that hogs my CPU whenever I hit return.
18
+ interactor :off
19
+
20
+ group :spec do
21
+ guard :rspec, cmd: "bundle exec rspec" do
22
+ dsl = Guard::RSpec::Dsl.new(self)
23
+
24
+ # RSpec files
25
+ rspec = dsl.rspec
26
+ watch(rspec.spec_helper) { rspec.spec_dir }
27
+ watch(rspec.spec_support) { rspec.spec_dir }
28
+ watch(rspec.spec_files)
29
+ spec_files = rspec.spec_files
30
+
31
+ # # Ruby files
32
+ ruby = dsl.ruby
33
+ watch(ruby.lib_files) { |m| rspec.spec.(m[1]) }
34
+ ruby_lib_files = ruby.lib_files
35
+ end
36
+
37
+
38
+ puts "README pattern: %p" % README_FILE
39
+ puts "ruby lib files pattern: %p" % ruby_lib_files
40
+ puts "spec files pattern: %p" % spec_files
41
+ end
42
+
43
+ group :syntax_check do
44
+ guard :shell do
45
+ # check Ruby syntax
46
+ watch(Regexp.union(ruby_lib_files, spec_files)) do |m|
47
+ puts "Checking Ruby syntax of %p ..." % m[0]
48
+ if not system("ruby -c #{m[0]}")
49
+ n "#{m[0]} is incorrect", 'Ruby Syntax', :failed
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ YARD_OPTS = "--use-cache .yardoc/cache.db"
56
+
57
+ group :doc do
58
+ guard 'yard' do
59
+ watch(Regexp.union(README_FILE, ruby_lib_files))
60
+ end
61
+ end
data/LICENSE ADDED
@@ -0,0 +1,5 @@
1
+ Copyright (c) 2016, Patrik Wenger
2
+
3
+ Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
4
+
5
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
data/Procfile ADDED
@@ -0,0 +1,3 @@
1
+ doc: bundle exec guard -g doc
2
+ spec: bundle exec guard -g spec
3
+ syntax_check: bundle exec guard -g syntax_check
data/README.md ADDED
@@ -0,0 +1,408 @@
1
+ [![Build Status on Travis CI](https://travis-ci.org/paddor/cztop.svg?branch=master)](https://travis-ci.org/paddor/cztop?branch=master)
2
+ [![Code Climate](https://codeclimate.com/repos/56677a7849f50a141c001784/badges/48f3cca3c62df9e4b17b/gpa.svg)](https://codeclimate.com/repos/56677a7849f50a141c001784/feed)
3
+ [![Inline docs](http://inch-ci.org/github/paddor/cztop.svg?branch=master&style=shields)](http://inch-ci.org/github/paddor/cztop)
4
+ [![Dependency Status](https://gemnasium.com/paddor/cztop.svg)](https://gemnasium.com/paddor/cztop)
5
+ [![Coverage Status](https://coveralls.io/repos/paddor/cztop/badge.svg?branch=master&service=github)](https://coveralls.io/github/paddor/cztop?branch=master)
6
+
7
+ # CZTop
8
+
9
+ ```
10
+ _________ _____________________
11
+ \_ ___ \ \____ /\__ ___/____ ______
12
+ / \ \/ / / | | / _ \ \____ \
13
+ \ \____ / /_ | | ( <_> )| |_> >
14
+ \______ //_______ \ |____| \____/ | __/
15
+ \/ \/ |__|
16
+ ```
17
+
18
+ CZTop is a CZMQ binding for Ruby. It is based on
19
+ [czmq-ffi-gen](https://github.com/paddor/czmq-ffi-gen), the generated low-level
20
+ FFI binding of [CZMQ](https://github.com/zeromq/czmq) and has a focus on being
21
+ easy to use for Rubyists (POLS) and providing first class support for security
22
+ mechanisms (like CURVE).
23
+
24
+ ## Reasons
25
+
26
+ Why another CZMQ Ruby binding? Here is a list of existing projects I found and
27
+ the issues with them, from my point of view:
28
+
29
+ * [Asmod4n/ruby-ffi-czmq](https://github.com/Asmod4n/ruby-ffi-czmq)
30
+ * outdated
31
+ * according to its author, it's an "abomination"
32
+ * [methodmissing/rbczmq](https://github.com/methodmissing/rbczmq)
33
+ * no support for security features (see [methodmissing/rbczmq#28](https://github.com/methodmissing/rbczmq/issues/28))
34
+ * no JRuby support (see [methodmissing/rbczmq#48](https://github.com/methodmissing/rbczmq/issues/48))
35
+ * doesn't feel like Ruby
36
+ * [mtortonesi/ruby-czmq](https://github.com/mtortonesi/ruby-czmq)
37
+ * no tests
38
+ * outdated
39
+ * doesn't feel like Ruby
40
+ * [chuckremes/ffi-rzmq](https://github.com/chuckremes/ffi-rzmq)
41
+ * low level ZMQ gem, not CZMQ
42
+
43
+ Furthermore, I knew about the generated low-level Ruby FFI binding in the
44
+ [zeromq/czmq](https://github.com/zeromq/czmq) repository. I wanted to make use
45
+ of it because I love that it's generated (and thus, most likely correct
46
+ and up-to-date). Unfortunately, it was in pretty bad shape and missing a few
47
+ CZMQ classes.
48
+
49
+ So I decided to improve the quality and usability of the binding and add the
50
+ missing classes. The result is
51
+ [czmq-ffi-gen](https://github.com/paddor/czmq-ffi-gen) which provides a solid
52
+ foundation for CZTop.
53
+
54
+ ## Goals
55
+
56
+ Here are some some of the goals I have/had in mind for this library:
57
+
58
+ - [x] as easy as possible, Ruby-esque API
59
+ - [x] first class support for security (CURVE mechanism)
60
+ - [x] including handling of certificates
61
+ - [x] support MRI, Rubinius, and JRuby
62
+ - [x] high-quality API documentation
63
+ - [x] 100% test coverage
64
+ - [x] provide a portable Z85 implementation
65
+ * unlike [fpesce/z85](https://github.com/fpesce/z85), which is a C extension
66
+ - [ ] use it to replace the [Celluloid::ZMQ](https://github.com/celluloid/celluloid-zmq) part of [Celluloid](https://github.com/celluloid/celluloid)
67
+ - [ ] implement some of the missing (CZMQ based) Ruby examples in the [ZMQ Guide](http://zguide.zeromq.org/page:all)
68
+
69
+ ## Overview
70
+
71
+ ### Class Hierarchy
72
+
73
+ Here's an overview of the core classes:
74
+
75
+ * CZTop
76
+ * Actor
77
+ * Authentiator < Actor
78
+ * Beacon < Actor
79
+ * Certificate
80
+ * Config
81
+ * Frame
82
+ * Message
83
+ * Monitor < Actor
84
+ * Proxy < Actor
85
+ * Poller
86
+ * Socket
87
+ * REQ < Socket
88
+ * REP < Socket
89
+ * ROUTER < Socket
90
+ * DEALER < Socket
91
+ * PUSH < Socket
92
+ * PULL < Socket
93
+ * PUB < Socket
94
+ * SUB < Socket
95
+ * XPUB < Socket
96
+ * XSUB < Socket
97
+ * PAIR < Socket
98
+ * STREAM < Socket
99
+ * CLIENT < Socket
100
+ * SERVER < Socket
101
+ * Z85
102
+ * Padded < Z85
103
+
104
+ More information in the [API documentation](http://www.rubydoc.info/github/paddor/cztop).
105
+
106
+ ### Features
107
+
108
+ * Ruby-like API
109
+ * method names
110
+ * sending a message via a socket is done with `Socket#<<`
111
+ * `socket << "simple message"`
112
+ * `socket << ["multi", "frame", "message"]`
113
+ * `#x=` methods instead of `#set_x` (e.g. socket options)
114
+ * `#[]` where it makes sense (e.g. on a Message, Config, or Certificate)
115
+ * no manual error checking needed
116
+ * if there's an error, an appropriate exception is raised
117
+ * of course, no manual dealing with the ZMQ context
118
+ * easy security
119
+ * use `Socket#CURVE_server!(cert)` on the server
120
+ * and `Socket#CURVE_client!(client_cert, server_cert)` on the client
121
+ * socket types as Ruby classes
122
+ * no need to manually pass some constant
123
+ * but you can: `CZTop::Socket.new_by_type(:REP)`
124
+ * e.g. `#subscribe` only exists on CZTop::Socket::SUB
125
+ * SERVER and CLIENT ready
126
+ * see CZTop::Socket::SERVER and CZTop::Socket::CLIENT
127
+ * there are `#routing_id` and `#routing_id=` on the following classes:
128
+ * CZTop::Message
129
+ * CZTop::Frame
130
+ * requires ZMQ >= 4.2
131
+ * ZMTP 3.1 heartbeat ready
132
+ * `socket.options.heartbeat_ivl = 2000`
133
+ * `socket.options.heartbeat_timeout = 8000`
134
+ * requires ZMQ >= 4.2
135
+
136
+ ## Requirements
137
+
138
+ You'll need:
139
+
140
+ * CZMQ >= 3.0.2
141
+ * ZMQ >= 4.0
142
+
143
+ For security mechanisms like CURVE, you'll need:
144
+
145
+ * [libsodium](https://github.com/jedisct1/libsodium)
146
+
147
+ To install on OSX using homebrew, run:
148
+
149
+ $ brew install libsodium
150
+ $ brew install zmq --with-libsodium
151
+ $ brew install czmq
152
+
153
+ If you're running Linux, go check [this page](http://zeromq.org/distro:_start)
154
+ to get more help. Make sure to install CZMQ, not only ZMQ.
155
+
156
+ **Warning**: To make use of the full feature set of CZTop (including
157
+ CLIENT/SERVER sockets and ZMTP 3.1 heartbeats), you'll need to install both ZMQ
158
+ and CZMQ from master, like this:
159
+
160
+ # instead of the last two commands from above
161
+ $ brew install zmq --with-libsodium --HEAD
162
+ $ brew install czmq --HEAD
163
+
164
+ See next section.
165
+
166
+ ### Known Issues if using the current stable releases
167
+
168
+ When using ZMQ 4.1/4.0:
169
+ * no CLIENT/SERVER sockets. Don't try.
170
+ * no ZMTP 3.1 heartbeats. Setting the options will have no effect.
171
+
172
+ When using CZMQ 3.0:
173
+ * don't use `Certificate#[]=` to unset meta data (by passing `nil`)
174
+ * `zcert_unset_meta()` was added more recently for that case
175
+ * see [zeromq/czmq#1248](https://github.com/zeromq/czmq/pull/1248)
176
+ * if you use Beacon, make sure you also call `Beacon#configure`. Otherwise it closes STDIN when being destroyed.
177
+ * see [zeromq/czmq#1281](https://github.com/zeromq/czmq/issues/1281)
178
+ * no CLIENT/SERVER sockets. Don't try.
179
+ * no ZMTP 3.1 heartbeats. Don't try.
180
+
181
+ ### Supported Ruby versions
182
+
183
+ See [.travis.yml](https://github.com/paddor/cztop/blob/master/.travis.yml) for a list of Ruby versions against which CZTop
184
+ is tested.
185
+
186
+ At the time of writing, these include:
187
+
188
+ * MRI (2.3, 2.2.4, 2.1.8)
189
+ * Rubinius (HEAD)
190
+ * JRuby 9000 (HEAD)
191
+
192
+ ## Installation
193
+
194
+ To use this gem, add this line to your application's Gemfile:
195
+
196
+ ```ruby
197
+ gem 'cztop'
198
+ ```
199
+
200
+ And then execute:
201
+
202
+ $ bundle
203
+
204
+ Or install it yourself as:
205
+
206
+ $ gem install cztop
207
+
208
+ ## Usage
209
+
210
+ See the [examples](https://github.com/paddor/cztop/blob/master/examples) directory for some examples. Here's a very simple one:
211
+
212
+ ### rep.rb:
213
+
214
+ ```ruby
215
+ #!/usr/bin/env ruby
216
+ require_relative '../../lib/cztop'
217
+
218
+ # create and bind socket
219
+ socket = CZTop::Socket::REP.new("ipc:///tmp/req_rep_example")
220
+ puts "<<< Socket bound to #{socket.last_endpoint.inspect}"
221
+
222
+ # Simply echo every message, with every frame String#upcase'd.
223
+ while msg = socket.receive
224
+ puts "<<< #{msg.to_a.inspect}"
225
+ socket << msg.to_a.map(&:upcase)
226
+ end
227
+ ```
228
+
229
+ ### req.rb:
230
+
231
+ ```ruby
232
+ #!/usr/bin/env ruby
233
+ require_relative '../../lib/cztop'
234
+
235
+ # connect
236
+ socket = CZTop::Socket::REQ.new("ipc:///tmp/req_rep_example")
237
+ puts ">>> Socket connected."
238
+
239
+ # simple string
240
+ socket << "foobar"
241
+ msg = socket.receive
242
+ puts ">>> #{msg.to_a.inspect}"
243
+
244
+ # multi frame message as array
245
+ socket << %w[foo bar baz]
246
+ msg = socket.receive
247
+ puts ">>> #{msg.to_a.inspect}"
248
+
249
+ # manually instantiating a Message
250
+ msg = CZTop::Message.new("bla")
251
+ msg << "another frame" # append a frame
252
+ socket << msg
253
+ msg = socket.receive
254
+ puts ">>> #{msg.to_a.inspect}"
255
+
256
+ ##
257
+ # This will send 20 additional messages:
258
+ #
259
+ # ./req.rb 20
260
+ #
261
+ if ARGV.first
262
+ ARGV.first.to_i.times do
263
+ socket << ["fooooooooo", "baaaaaar"]
264
+ puts ">>> " + socket.receive.to_a.inspect
265
+ end
266
+ end
267
+ ```
268
+
269
+ ### Running it
270
+
271
+ ```
272
+ $ ./rep.rb & ./req.rb 3
273
+ [3] 35321
274
+ >>> Socket connected.
275
+ <<< Socket bound to "ipc:///tmp/req_rep_example"
276
+ <<< ["foobar"]
277
+ >>> ["FOOBAR"]
278
+ <<< ["foo", "bar", "baz"]
279
+ >>> ["FOO", "BAR", "BAZ"]
280
+ <<< ["bla", "another frame"]
281
+ >>> ["BLA", "ANOTHER FRAME"]
282
+ <<< ["fooooooooo", "baaaaaar"]
283
+ >>> ["FOOOOOOOOO", "BAAAAAAR"]
284
+ <<< ["fooooooooo", "baaaaaar"]
285
+ >>> ["FOOOOOOOOO", "BAAAAAAR"]
286
+ <<< ["fooooooooo", "baaaaaar"]
287
+ >>> ["FOOOOOOOOO", "BAAAAAAR"]
288
+ $
289
+ ```
290
+
291
+ ## Documentation
292
+
293
+ The API should be fairly straight-forward to anyone who is familiar with CZMQ
294
+ and Ruby. The following API documentation is currently available:
295
+
296
+ * [YARD API documentation](http://www.rubydoc.info/github/paddor/cztop)
297
+
298
+ Feel free to start a [wiki](https://github.com/paddor/cztop/wiki) page.
299
+
300
+ ## Performance
301
+
302
+ Performance should be pretty okay since this is based on czmq-ffi-gen, which is
303
+ reasonably thin. CZTop is basically only a convenience layer on top, with some
304
+ nice error checking. But hey, it's Ruby. Don't expect 5M messages per second
305
+ with a latency of 3us.
306
+
307
+ The measured latency on my laptop ranges from ~20us to ~60us per message for
308
+ 1kb messages, depending on whether transport is inproc, IPC, or TCP/IP.
309
+
310
+ Make sure you check out the
311
+ [perf](https://github.com/paddor/cztop/blob/master/perf) directory for latency
312
+ and throughput measurement scripts.
313
+
314
+ ## TODO
315
+
316
+ * [x] pack generated code into its own gem ([czmq-ffi-gen](https://github.com/paddor/czmq-ffi-gen))
317
+ * think of a neat Ruby API, including:
318
+ - [x] Actor
319
+ - [x] Beacon
320
+ - [x] Certificate
321
+ - [x] Socket
322
+ - [50%] access to all socket options
323
+ - [x] Security mechanisms
324
+ - [x] Message
325
+ - [x] Frame
326
+ - [x] enumerable Frames
327
+ - [x] Authenticator
328
+ - [x] Loop
329
+ - [x] Monitor
330
+ - [x] Poller
331
+ - [x] Proxy
332
+ - [x] Config
333
+ - [x] Z85
334
+ * write the missing XML API files in CZMQ
335
+ - [x] zarmour.xml
336
+ - [x] zconfig.xml
337
+ - [x] zsock_option.xml
338
+ - [x] zcert.xml
339
+ - [x] zcertstore.xml
340
+ * [x] check availability of libsodium within CZTop
341
+ * [x] read error strings for exceptions where appropriate (zmq_strerror)
342
+ * [x] add support for ZMTP 3.1 heartbeats in CZMQ
343
+ * [x] add padded variant of Z85
344
+ * add more examples
345
+ * [x] [simple REQ/REP](https://github.com/paddor/cztop/tree/master/examples/simple_req_rep)
346
+ * [x] [Taxy System](https://github.com/paddor/cztop/tree/master/examples/taxi_system) with CURVE security and heartbeating
347
+ * [x] change from ROUTER/DEALER to SERVER/CLIENT
348
+ * [x] [Actor](https://github.com/paddor/cztop/tree/master/examples/ruby_actor) with Ruby block
349
+ * [ ] PUSH/PULL
350
+ * [ ] PUB/SUB
351
+ * [ ] add performance benchmarks
352
+ * [x] inproc latency
353
+ * [x] inproc throughput
354
+ * [x] local/remote latency
355
+ * [ ] local/remote throughput
356
+ * see [perf](https://github.com/paddor/cztop/blob/master/perf) directory
357
+ * [x] support older versions of ZMQ
358
+ * [x] ZMQ HEAD
359
+ * [x] tested on CI
360
+ * [x] ZMQ 4.1
361
+ * [x] tested on CI
362
+ * [x] ZMQ 4.0
363
+ * [x] tested on CI
364
+ * [ ] ZMQ 3.2
365
+ * too big a pain ([d5172ab](https://github.com/paddor/czmq-ffi-gen/commit/d5172ab6db64999c50ba24f71569acf1dd45af51))
366
+ * [x] support multiple versions of CZMQ
367
+ * [x] CZMQ HEAD
368
+ * [x] test on CI
369
+ * [x] CZMQ 3.0.2 (current stable)
370
+ * no `zcert_meta_unset()` ([zeromq/czmq#1246](https://github.com/zeromq/czmq/issues/1246))
371
+ * [x] adapt czmq-ffi-gen so it doesn't raise while `attach_function`
372
+ * no `zproc`(especially no `zproc_has_curve()`)
373
+ * [x] adapt czmq-ffi-gen so it doesn't raise while `attach_function`, attach `zsys_has_curve()` instead (under same name)
374
+ * [x] adapt test suite to skip affected test examples
375
+ * [x] test on CI
376
+ * [x] port Poller to `zmq_poll()`
377
+ * backwards compatible (`#add_reader`, `#add_writer`, `#wait` behave the same)
378
+ * but in addition, it has `#readables` and `#writables` which return arrays of sockets
379
+ * level-triggered (not sure if `zmq_poll()` itelf is, but it'll be trivial)
380
+ * could then be used in Celluloid::ZMQ
381
+ * want to use `zmq_poller()` because it can deal with CLIENT/SERVER sockets and is the future
382
+ * but can't use it because
383
+ * it doesn't allow me to get all readable/writable sockets back after one call to `#wait`
384
+ * can't just recall `#wait` with zero timeout until it says there are no
385
+ more, because ZMQ sockets (option ZMQ_FD) are edge-triggered :-(
386
+ * maybe I don't really need that functionality, though
387
+ * can't use `zpoller`, because it doesn't support polling for writing
388
+ * [ ] add `Message#to_s`
389
+ * return frame as string, if there's only one frame
390
+ * raise if there are multiple frames
391
+ * only safe to use on messages from SERVER/CLIENT sockets
392
+ * single-part messages are the future
393
+ * [x] get rid of Loop
394
+ * cannot handle SERVER socket
395
+ * there are other timer libraries for Ruby
396
+ * Poller can be used to embed in an existing event loop (Celluloid), or make your own trivial one.
397
+
398
+ ## Contributing
399
+
400
+ Bug reports and pull requests are welcome on GitHub at https://github.com/paddor/cztop.
401
+
402
+ To run the tests before/after you made any changes to the source and have
403
+ created a test case for it, use `rake spec`.
404
+
405
+ ## License
406
+
407
+ The gem is available as open source under the terms of the [ISC License](http://opensource.org/licenses/ISC).
408
+ See the [LICENSE](https://github.com/paddor/cztop/blob/master/LICENSE) file.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "cztop"
5
+
6
+ require "pry"
7
+ Pry.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,9 @@
1
+ #!/bin/sh -x
2
+ set -e
3
+ mkdir -p vendor
4
+ cd vendor
5
+ git clone https://github.com/paddor/czmq-ffi-gen
6
+ cd czmq-ffi-gen
7
+ ci-scripts/install-libsodium
8
+ ci-scripts/install-libzmq
9
+ ci-scripts/install-libczmq
data/cztop.gemspec ADDED
@@ -0,0 +1,36 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cztop/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "cztop"
8
+ spec.version = CZTop::VERSION
9
+ spec.authors = ["Patrik Wenger"]
10
+ spec.email = ["paddor@gmail.com"]
11
+
12
+ spec.summary = %q{CZMQ Ruby binding, based on the generated low-level FFI bindings of CZMQ}
13
+ spec.homepage = "https://github.com/paddor/cztop"
14
+ spec.license = "ISC"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency "czmq-ffi-gen", "~> 0.7.0"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.10"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "rspec"
26
+ spec.add_development_dependency "minitest"
27
+ spec.add_development_dependency "rspec-given", "~> 3.8.0"
28
+ spec.add_development_dependency "pry"
29
+ spec.add_development_dependency "yard"
30
+ spec.add_development_dependency "guard"
31
+ spec.add_development_dependency "guard-rspec"
32
+ spec.add_development_dependency "guard-yard"
33
+ spec.add_development_dependency "guard-shell"
34
+ spec.add_development_dependency 'terminal-notifier-guard'
35
+ spec.add_development_dependency 'foreman'
36
+ end