ffi-rzmq 1.0.3 → 2.0.0

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.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +1 -1
  3. data/AUTHORS.txt +5 -1
  4. data/History.txt +19 -0
  5. data/README.rdoc +2 -4
  6. data/examples/README.rdoc +1 -3
  7. data/examples/{v3api/latency_measurement.rb → latency_measurement.rb} +1 -2
  8. data/examples/{v3api/local_lat.rb → local_lat.rb} +1 -1
  9. data/examples/{v3api/local_lat_poll.rb → local_lat_poll.rb} +4 -4
  10. data/examples/{v3api/local_throughput.rb → local_throughput.rb} +1 -1
  11. data/examples/{v3api/pub.rb → pub.rb} +1 -1
  12. data/examples/{v2api/publish_subscribe.rb → publish_subscribe.rb} +2 -2
  13. data/examples/{v2api/remote_lat.rb → remote_lat.rb} +1 -1
  14. data/examples/{v3api/remote_throughput.rb → remote_throughput.rb} +4 -3
  15. data/examples/{v2api/reqrep_poll.rb → reqrep_poll.rb} +3 -4
  16. data/examples/{v2api/request_response.rb → request_response.rb} +1 -2
  17. data/examples/{v3api/sub.rb → sub.rb} +1 -2
  18. data/examples/{v3api/throughput_measurement.rb → throughput_measurement.rb} +1 -1
  19. data/examples/{v3api/xreqxrep_poll.rb → xreqxrep_poll.rb} +6 -7
  20. data/ffi-rzmq.gemspec +4 -4
  21. data/lib/ffi-rzmq.rb +2 -3
  22. data/lib/ffi-rzmq/context.rb +25 -53
  23. data/lib/ffi-rzmq/device.rb +8 -4
  24. data/lib/ffi-rzmq/message.rb +24 -30
  25. data/lib/ffi-rzmq/poll.rb +5 -16
  26. data/lib/ffi-rzmq/socket.rb +129 -278
  27. data/lib/ffi-rzmq/util.rb +11 -36
  28. data/lib/ffi-rzmq/version.rb +1 -1
  29. data/spec/context_spec.rb +3 -8
  30. data/spec/device_spec.rb +10 -9
  31. data/spec/nonblocking_recv_spec.rb +7 -7
  32. data/spec/pushpull_spec.rb +8 -7
  33. data/spec/reqrep_spec.rb +6 -6
  34. data/spec/socket_spec.rb +43 -130
  35. data/spec/spec_helper.rb +3 -11
  36. metadata +77 -104
  37. data/examples/v2api/latency_measurement.rb +0 -139
  38. data/examples/v2api/local_lat.rb +0 -58
  39. data/examples/v2api/local_lat_poll.rb +0 -66
  40. data/examples/v2api/local_throughput.rb +0 -58
  41. data/examples/v2api/pub.rb +0 -46
  42. data/examples/v2api/remote_throughput.rb +0 -39
  43. data/examples/v2api/sub.rb +0 -74
  44. data/examples/v2api/throughput_measurement.rb +0 -138
  45. data/examples/v2api/xreqxrep_poll.rb +0 -93
  46. data/examples/v3api/publish_subscribe.rb +0 -82
  47. data/examples/v3api/remote_lat.rb +0 -71
  48. data/examples/v3api/reqrep_poll.rb +0 -62
  49. data/examples/v3api/request_response.rb +0 -40
  50. data/lib/ffi-rzmq/constants.rb +0 -187
  51. data/lib/ffi-rzmq/libc.rb +0 -19
  52. data/lib/ffi-rzmq/libzmq.rb +0 -283
@@ -1,82 +0,0 @@
1
- require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'ffi-rzmq')
2
-
3
-
4
- def assert(rc)
5
- raise "Last API call failed at #{caller(1)}" unless rc >= 0
6
- end
7
-
8
- link = "tcp://127.0.0.1:5555"
9
-
10
- begin
11
- ctx = ZMQ::Context.new
12
- s1 = ctx.socket(ZMQ::PUB)
13
- s2 = ctx.socket(ZMQ::SUB)
14
- s3 = ctx.socket(ZMQ::SUB)
15
- s4 = ctx.socket(ZMQ::SUB)
16
- s5 = ctx.socket(ZMQ::SUB)
17
- rescue ContextError => e
18
- STDERR.puts "Failed to allocate context or socket!"
19
- raise
20
- end
21
-
22
- assert(s1.setsockopt(ZMQ::LINGER, 100))
23
- assert(s2.setsockopt(ZMQ::SUBSCRIBE, '')) # receive all
24
- assert(s3.setsockopt(ZMQ::SUBSCRIBE, 'animals')) # receive any starting with this string
25
- assert(s4.setsockopt(ZMQ::SUBSCRIBE, 'animals.dog'))
26
- assert(s5.setsockopt(ZMQ::SUBSCRIBE, 'animals.cat'))
27
-
28
- assert(s1.bind(link))
29
- assert(s2.connect(link))
30
- assert(s3.connect(link))
31
- assert(s4.connect(link))
32
- assert(s5.connect(link))
33
-
34
- sleep 1
35
-
36
- topic = "animals.dog"
37
- payload = "Animal crackers!"
38
-
39
- s1.identity = "publisher-A"
40
- puts "sending"
41
- # use the new multi-part messaging support to
42
- # automatically separate the topic from the body
43
- assert(s1.send_string(topic, ZMQ::SNDMORE))
44
- assert(s1.send_string(payload, ZMQ::SNDMORE))
45
- assert(s1.send_string(s1.identity))
46
-
47
- topic = ''
48
- assert(s2.recv_string(topic))
49
-
50
- body = ''
51
- assert(s2.recv_string(body)) if s2.more_parts?
52
-
53
- identity = ''
54
- assert(s2.recv_string(identity)) if s2.more_parts?
55
- puts "s2 received topic [#{topic}], body [#{body}], identity [#{identity}]"
56
-
57
-
58
-
59
- topic = ''
60
- assert(s3.recv_string(topic))
61
-
62
- body = ''
63
- assert(s3.recv_string(body)) if s3.more_parts?
64
- puts "s3 received topic [#{topic}], body [#{body}]"
65
-
66
- topic = ''
67
- assert(s4.recv_string(topic))
68
-
69
- body = ''
70
- assert(s4.recv_string(body)) if s4.more_parts?
71
- puts "s4 received topic [#{topic}], body [#{body}]"
72
-
73
- s5_string = ''
74
- rc = s5.recv_string(s5_string, ZMQ::NonBlocking)
75
- eagain = (rc == -1 && ZMQ::Util.errno == ZMQ::EAGAIN)
76
- puts(eagain ? "s5 received no messages" : "s5 FAILED")
77
-
78
- [s1, s2, s3, s4, s5].each do |socket|
79
- assert(socket.close)
80
- end
81
-
82
- ctx.terminate
@@ -1,71 +0,0 @@
1
- #
2
- # Copyright (c) 2007-2010 iMatix Corporation
3
- #
4
- # This file is part of 0MQ.
5
- #
6
- # 0MQ is free software; you can redistribute it and/or modify it under
7
- # the terms of the Lesser GNU General Public License as published by
8
- # the Free Software Foundation; either version 3 of the License, or
9
- # (at your option) any later version.
10
- #
11
- # 0MQ is distributed in the hope that it will be useful,
12
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- # Lesser GNU General Public License for more details.
15
- #
16
- # You should have received a copy of the Lesser GNU General Public License
17
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
18
-
19
-
20
- require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'ffi-rzmq')
21
-
22
- if ARGV.length < 3
23
- puts "usage: ruby remote_lat.rb <connect-to> <message-size> <roundtrip-count>"
24
- exit
25
- end
26
-
27
- def assert(rc)
28
- raise "Last API call failed at #{caller(1)}" unless rc >= 0
29
- end
30
-
31
- connect_to = ARGV[0]
32
- message_size = ARGV[1].to_i
33
- roundtrip_count = ARGV[2].to_i
34
-
35
- begin
36
- ctx = ZMQ::Context.new
37
- s = ctx.socket(ZMQ::REQ)
38
- rescue ContextError => e
39
- STDERR.puts "Failed to allocate context or socket!"
40
- raise
41
- end
42
-
43
- assert(s.setsockopt(ZMQ::LINGER, 100))
44
- assert(s.connect(connect_to))
45
-
46
- msg = "#{ '3' * message_size }"
47
-
48
- start_time = Time.now
49
-
50
- roundtrip_count.times do
51
- assert(s.send_string(msg, 0))
52
-
53
- msg = ''
54
- assert(s.recv_string(msg, 0))
55
-
56
- raise "Message size doesn't match, expected [#{message_size}] but received [#{msg.size}]" if message_size != msg.size
57
- end
58
-
59
- end_time = Time.now
60
- elapsed_secs = (end_time.to_f - start_time.to_f)
61
- elapsed_usecs = elapsed_secs * 1000000
62
- latency = elapsed_usecs / roundtrip_count / 2
63
-
64
- puts "message size: %i [B]" % message_size
65
- puts "roundtrip count: %i" % roundtrip_count
66
- puts "throughput (msgs/s): %i" % (roundtrip_count / elapsed_secs)
67
- puts "mean latency: %.3f [us]" % latency
68
-
69
- assert(s.close)
70
-
71
- ctx.terminate
@@ -1,62 +0,0 @@
1
-
2
- require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'ffi-rzmq')
3
-
4
-
5
- def assert(rc)
6
- raise "Last API call failed at #{caller(1)}" unless rc >= 0
7
- end
8
-
9
- link = "tcp://127.0.0.1:5554"
10
-
11
- begin
12
- ctx = ZMQ::Context.new
13
- s1 = ctx.socket(ZMQ::REQ)
14
- s2 = ctx.socket(ZMQ::REP)
15
- rescue ContextError => e
16
- STDERR.puts "Failed to allocate context or socket!"
17
- raise
18
- end
19
-
20
- assert(s1.setsockopt(ZMQ::LINGER, 100))
21
- assert(s2.setsockopt(ZMQ::LINGER, 100))
22
-
23
- assert(s1.connect(link))
24
- assert(s2.bind(link))
25
-
26
- poller = ZMQ::Poller.new
27
- poller.register_readable(s2)
28
- poller.register_writable(s1)
29
-
30
- start_time = Time.now
31
- @unsent = true
32
-
33
- until @done do
34
- assert(poller.poll_nonblock)
35
-
36
- # send the message after 5 seconds
37
- if Time.now - start_time > 5 && @unsent
38
- payload = "#{ '3' * 1024 }"
39
-
40
- puts "sending payload nonblocking"
41
- assert(s1.send_string(payload, ZMQ::NonBlocking))
42
- @unsent = false
43
- end
44
-
45
- # check for messages after 1 second
46
- if Time.now - start_time > 1
47
- poller.readables.each do |sock|
48
- received_msg = ''
49
- assert(sock.recv_string(received_msg, ZMQ::NonBlocking))
50
-
51
- puts "message received [#{received_msg}]"
52
- @done = true
53
- end
54
- end
55
- end
56
-
57
- puts "executed in [#{Time.now - start_time}] seconds"
58
-
59
- assert(s1.close)
60
- assert(s2.close)
61
-
62
- ctx.terminate
@@ -1,40 +0,0 @@
1
-
2
- require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'ffi-rzmq')
3
-
4
-
5
- def assert(rc)
6
- raise "Last API call failed at #{caller(1)}" unless rc >= 0
7
- end
8
-
9
- link = "tcp://127.0.0.1:5555"
10
-
11
- begin
12
- ctx = ZMQ::Context.new
13
- s1 = ctx.socket(ZMQ::REQ)
14
- s2 = ctx.socket(ZMQ::REP)
15
- rescue ContextError => e
16
- STDERR.puts "Failed to allocate context or socket"
17
- raise
18
- end
19
-
20
- assert(s1.setsockopt(ZMQ::LINGER, 100))
21
- assert(s2.setsockopt(ZMQ::LINGER, 100))
22
-
23
- assert(s2.bind(link))
24
- assert(s1.connect(link))
25
-
26
- payload = "#{ '3' * 2048 }"
27
- sent_msg = ZMQ::Message.new(payload)
28
- received_msg = ZMQ::Message.new
29
-
30
- assert(s1.sendmsg(sent_msg))
31
- assert(s2.recvmsg(received_msg))
32
-
33
- result = payload == received_msg.copy_out_string ? "Request received" : "Received wrong payload"
34
-
35
- p result
36
-
37
- assert(s1.close)
38
- assert(s2.close)
39
-
40
- ctx.terminate
@@ -1,187 +0,0 @@
1
- module ZMQ
2
- # Set up all of the constants that are *common* to all API
3
- # versions
4
-
5
- # Socket types
6
- PAIR = 0
7
- PUB = 1
8
- SUB = 2
9
- REQ = 3
10
- REP = 4
11
- XREQ = 5
12
- XREP = 6
13
- PULL = 7
14
- PUSH = 8
15
-
16
- SocketTypeNameMap = {
17
- PAIR => "PAIR",
18
- PUB => "PUB",
19
- SUB => "SUB",
20
- REQ => "REQ",
21
- REP => "REP",
22
- PULL => "PULL",
23
- PUSH => "PUSH",
24
- XREQ => "XREQ",
25
- XREP => "XREP"
26
- }
27
-
28
- # Socket options
29
- AFFINITY = 4
30
- SUBSCRIBE = 6
31
- UNSUBSCRIBE = 7
32
- RATE = 8
33
- RECOVERY_IVL = 9
34
- SNDBUF = 11
35
- RCVBUF = 12
36
- RCVMORE = 13
37
- FD = 14
38
- EVENTS = 15
39
- TYPE = 16
40
- LINGER = 17
41
- RECONNECT_IVL = 18
42
- BACKLOG = 19
43
- RECONNECT_IVL_MAX = 21
44
- RCVTIMEO = 27
45
- SNDTIMEO = 28
46
-
47
- # Send/recv options
48
- SNDMORE = 2
49
-
50
- # I/O multiplexing
51
-
52
- POLL = 1
53
- POLLIN = 1
54
- POLLOUT = 2
55
- POLLERR = 4
56
-
57
- # Socket errors
58
- EAGAIN = Errno::EAGAIN::Errno
59
- EINVAL = Errno::EINVAL::Errno
60
- ENOMEM = Errno::ENOMEM::Errno
61
- ENODEV = Errno::ENODEV::Errno
62
- EFAULT = Errno::EFAULT::Errno
63
- EINTR = Errno::EINTR::Errno
64
-
65
- # ZMQ errors
66
- HAUSNUMERO = 156384712
67
- EFSM = (HAUSNUMERO + 51)
68
- ENOCOMPATPROTO = (HAUSNUMERO + 52)
69
- ETERM = (HAUSNUMERO + 53)
70
- EMTHREAD = (HAUSNUMERO + 54)
71
-
72
- # Rescue unknown constants and use the ZeroMQ defined values
73
- # Usually only happens on Windows though some don't resolve on
74
- # OSX too (ENOTSUP)
75
- ENOTSUP = Errno::ENOTSUP::Errno rescue (HAUSNUMERO + 1)
76
- EPROTONOSUPPORT = Errno::EPROTONOSUPPORT::Errno rescue (HAUSNUMERO + 2)
77
- ENOBUFS = Errno::ENOBUFS::Errno rescue (HAUSNUMERO + 3)
78
- ENETDOWN = Errno::ENETDOWN::Errno rescue (HAUSNUMERO + 4)
79
- EADDRINUSE = Errno::EADDRINUSE::Errno rescue (HAUSNUMERO + 5)
80
- EADDRNOTAVAIL = Errno::EADDRNOTAVAIL::Errno rescue (HAUSNUMERO + 6)
81
- ECONNREFUSED = Errno::ECONNREFUSED::Errno rescue (HAUSNUMERO + 7)
82
- EINPROGRESS = Errno::EINPROGRESS::Errno rescue (HAUSNUMERO + 8)
83
- ENOTSOCK = Errno::ENOTSOCK::Errno rescue (HAUSNUMERO + 9)
84
- EMSGSIZE = Errno::EMSGSIZE::Errno rescue (HAUSNUMERO + 10)
85
- EAFNOSUPPORT = Errno::EAFNOSUPPORT::Errno rescue (HAUSNUMERO + 11)
86
- ENETUNREACH = Errno::ENETUNREACH::Errno rescue (HAUSNUMERO + 12)
87
- ECONNABORTED = Errno::ECONNABORTED::Errno rescue (HAUSNUMERO + 13)
88
- ECONNRESET = Errno::ECONNRESET::Errno rescue (HAUSNUMERO + 14)
89
- ENOTCONN = Errno::ENOTCONN::Errno rescue (HAUSNUMERO + 15)
90
- ETIMEDOUT = Errno::ETIMEDOUT::Errno rescue (HAUSNUMERO + 16)
91
- EHOSTUNREACH = Errno::EHOSTUNREACH::Errno rescue (HAUSNUMERO + 17)
92
- ENETRESET = Errno::ENETRESET::Errno rescue (HAUSNUMERO + 18)
93
-
94
- # Device Types
95
- STREAMER = 1
96
- FORWARDER = 2
97
- QUEUE = 3
98
- end # module ZMQ
99
-
100
-
101
- if ZMQ::LibZMQ.version2?
102
- module ZMQ
103
- # Socket types
104
- UPSTREAM = PULL
105
- DOWNSTREAM = PUSH
106
- DEALER = XREQ
107
- ROUTER = XREP
108
-
109
- SocketTypeNameMap[ROUTER] = 'ROUTER'
110
- SocketTypeNameMap[DEALER] = 'DEALER'
111
-
112
- # Socket options
113
- HWM = 1
114
- IDENTITY = 5
115
- MCAST_LOOP = 10
116
- SWAP = 3
117
- RECOVERY_IVL_MSEC = 20
118
-
119
- # Send/recv options
120
- NOBLOCK = 1
121
- NonBlocking = NOBLOCK
122
- end
123
- end # version2?
124
-
125
-
126
- if ZMQ::LibZMQ.version3?
127
- module ZMQ
128
- # Socket types
129
- XPUB = 9
130
- XSUB = 10
131
- DEALER = XREQ
132
- ROUTER = XREP
133
-
134
- SocketTypeNameMap[ROUTER] = 'ROUTER'
135
- SocketTypeNameMap[DEALER] = 'DEALER'
136
- SocketTypeNameMap[XPUB] = 'XPUB'
137
- SocketTypeNameMap[XSUB] = 'XSUB'
138
-
139
- # Context options
140
- IO_THREADS = 1
141
- MAX_SOCKETS = 2
142
- IO_THREADS_DFLT = 1
143
- MAX_SOCKETS_DFLT = 1024
144
-
145
- # Socket options
146
- IDENTITY = 5
147
- MAXMSGSIZE = 22
148
- SNDHWM = 23
149
- RCVHWM = 24
150
- MULTICAST_HOPS = 25
151
- IPV4ONLY = 31
152
- LAST_ENDPOINT = 32
153
- ROUTER_BEHAVIOR = 33
154
- TCP_KEEPALIVE = 34
155
- TCP_KEEPALIVE_CNT = 35
156
- TCP_KEEPALIVE_IDLE = 36
157
- TCP_KEEPALIVE_INTVL = 37
158
- TCP_ACCEPT_FILTER = 38
159
-
160
- # Message options
161
- MORE = 1
162
-
163
- # Send/recv options
164
- DONTWAIT = 1
165
- SNDLABEL = 4
166
- NonBlocking = DONTWAIT
167
-
168
- # Socket events and monitoring
169
- EVENT_CONNECTED = 1
170
- EVENT_CONNECT_DELAYED = 2
171
- EVENT_CONNECT_RETRIED = 4
172
- EVENT_LISTENING = 8
173
- EVENT_BIND_FAILED = 16
174
- EVENT_ACCEPTED = 32
175
- EVENT_ACCEPT_FAILED = 64
176
- EVENT_CLOSED = 128
177
- EVENT_CLOSE_FAILED = 256
178
- EVENT_DISCONNECTED = 512
179
- EVENT_ALL = EVENT_CONNECTED | EVENT_CONNECT_DELAYED | EVENT_CONNECT_RETRIED |
180
- EVENT_LISTENING | EVENT_BIND_FAILED | EVENT_ACCEPTED |
181
- EVENT_ACCEPT_FAILED | EVENT_CLOSED | EVENT_CLOSE_FAILED |
182
- EVENT_DISCONNECTED
183
-
184
- # Socket & other errors
185
- EMFILE = Errno::EMFILE::Errno
186
- end
187
- end # version3?
@@ -1,19 +0,0 @@
1
-
2
- module LibC
3
- extend FFI::Library
4
- # figures out the correct libc for each platform including Windows
5
- library = ffi_lib(FFI::Library::LIBC).first
6
-
7
- # Size_t not working properly on Windows
8
- find_type(:size_t) rescue typedef(:ulong, :size_t)
9
-
10
- # memory allocators
11
- attach_function :malloc, [:size_t], :pointer
12
- attach_function :free, [:pointer], :void
13
-
14
- # get a pointer to the free function; used for ZMQ::Message deallocation
15
- Free = library.find_symbol('free')
16
-
17
- # memory movers
18
- attach_function :memcpy, [:pointer, :pointer, :size_t], :pointer
19
- end # module LibC