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,66 +0,0 @@
1
-
2
- require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'ffi-rzmq')
3
-
4
- if ARGV.length < 3
5
- puts "usage: ruby local_lat.rb <connect-to> <message-size> <roundtrip-count>"
6
- exit
7
- end
8
-
9
- link = ARGV[0]
10
- message_size = ARGV[1].to_i
11
- roundtrip_count = ARGV[2].to_i
12
-
13
- def assert(rc)
14
- raise "Last API call failed at #{caller(1)}" unless rc >= 0
15
- end
16
-
17
- begin
18
- ctx = ZMQ::Context.new
19
- s1 = ctx.socket(ZMQ::REQ)
20
- s2 = ctx.socket(ZMQ::REP)
21
- rescue ContextError => e
22
- STDERR.puts "Failed to allocate context or socket!"
23
- raise
24
- end
25
-
26
- assert(s1.setsockopt(ZMQ::LINGER, 100))
27
- assert(s2.setsockopt(ZMQ::LINGER, 100))
28
-
29
- assert(s1.connect(link))
30
- assert(s2.bind(link))
31
-
32
- poller = ZMQ::Poller.new
33
- poller.register_readable(s2)
34
- poller.register_readable(s1)
35
-
36
-
37
- start_time = Time.now
38
-
39
- # kick it off
40
- message = ZMQ::Message.new("a" * message_size)
41
- assert(s1.sendmsg(message, ZMQ::NonBlocking))
42
-
43
- i = roundtrip_count
44
-
45
- until i.zero?
46
- i -= 1
47
-
48
- assert(poller.poll_nonblock)
49
-
50
- poller.readables.each do |socket|
51
- received_message = ''
52
- assert(socket.recv_string(received_message, ZMQ::NonBlocking))
53
- assert(socket.sendmsg(ZMQ::Message.new(received_message), ZMQ::NonBlocking))
54
- end
55
- end
56
-
57
- elapsed_usecs = (Time.now.to_f - start_time.to_f) * 1_000_000
58
- latency = elapsed_usecs / roundtrip_count / 2
59
-
60
- puts "mean latency: %.3f [us]" % latency
61
- puts "received all messages in %.3f seconds" % (elapsed_usecs / 1_000_000)
62
-
63
- assert(s1.close)
64
- assert(s2.close)
65
-
66
- ctx.terminate
@@ -1,58 +0,0 @@
1
-
2
- require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'ffi-rzmq')
3
-
4
- if ARGV.length != 3
5
- puts "usage: ruby local_throughtput.rb <bind-to> <message-size> <message-count>"
6
- Process.exit
7
- end
8
-
9
- def assert(rc)
10
- raise "Last API call failed at #{caller(1)}" unless rc >= 0
11
- end
12
-
13
- bind_to = ARGV[0]
14
- message_size = ARGV[1].to_i
15
- message_count = ARGV[2].to_i
16
-
17
- begin
18
- ctx = ZMQ::Context.new
19
- s = ZMQ::Socket.new(ctx.pointer, ZMQ::SUB)
20
- rescue ContextError => e
21
- STDERR.puts "Failed to allocate context or socket!"
22
- raise
23
- end
24
-
25
- assert(s.setsockopt(ZMQ::LINGER, 100))
26
- assert(s.setsockopt(ZMQ::SUBSCRIBE, ""))
27
-
28
- assert(s.bind(bind_to))
29
-
30
- msg = ZMQ::Message.new
31
- assert(s.recvmsg(msg))
32
-
33
- start_time = Time.now
34
-
35
- i = 1
36
- while i < message_count
37
- assert(s.recvmsg(msg))
38
- i += 1
39
- end
40
-
41
- end_time = Time.now
42
-
43
- elapsed = (end_time.to_f - start_time.to_f) * 1000000
44
- if elapsed == 0
45
- elapsed = 1
46
- end
47
-
48
- throughput = message_count * 1000000 / elapsed
49
- megabits = throughput * message_size * 8 / 1000000
50
-
51
- puts "message size: %i [B]" % message_size
52
- puts "message count: %i" % message_count
53
- puts "mean throughput: %i [msg/s]" % throughput
54
- puts "mean throughput: %.3f [Mb/s]" % megabits
55
-
56
- assert(s.close)
57
-
58
- ctx.terminate
@@ -1,46 +0,0 @@
1
-
2
- require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'ffi-rzmq')
3
-
4
- if ARGV.length != 3
5
- puts "usage: ruby remote_throughput.rb <connect-to> <message-size> <message-count>"
6
- Process.exit
7
- end
8
-
9
- connect_to = ARGV[0]
10
- message_size = ARGV[1].to_i
11
- message_count = ARGV[2].to_i
12
-
13
- def assert(rc)
14
- raise "Last API call failed at #{caller(1)}" unless rc >= 0
15
- end
16
-
17
- begin
18
- ctx = ZMQ::Context.new
19
- s = ZMQ::Socket.new(ctx.pointer, ZMQ::PUB)
20
- rescue ContextError => e
21
- STDERR.puts "Could not allocate a context or socket!"
22
- raise
23
- end
24
-
25
- #assert(s.setsockopt(ZMQ::LINGER, 1_000))
26
- #assert(s.setsockopt(ZMQ::RCVHWM, 0))
27
- assert(s.setsockopt(ZMQ::HWM, 10))
28
- assert(s.bind(connect_to))
29
-
30
- # the sleep gives the downstream SUB socket a chance to register its
31
- # subscription filters with this PUB socket
32
- puts "Hit any key to start publishing"
33
- STDIN.gets
34
-
35
- i = 0
36
- while i < message_count
37
- msg = ZMQ::Message.new(i.to_s)
38
- assert(s.sendmsg(msg))
39
- puts i
40
- i += 1
41
- end
42
-
43
- sleep 10
44
- assert(s.close)
45
-
46
- ctx.terminate
@@ -1,39 +0,0 @@
1
-
2
- require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'ffi-rzmq')
3
-
4
- if ARGV.length != 3
5
- puts "usage: ruby remote_throughput.rb <connect-to> <message-size> <message-count>"
6
- Process.exit
7
- end
8
-
9
- connect_to = ARGV[0]
10
- message_size = ARGV[1].to_i
11
- message_count = ARGV[2].to_i
12
-
13
- def assert(rc)
14
- raise "Last API call failed at #{caller(1)}" unless rc >= 0
15
- end
16
-
17
- begin
18
- ctx = ZMQ::Context.new
19
- s = ZMQ::Socket.new(ctx.pointer, ZMQ::PUB)
20
- rescue ContextError => e
21
- STDERR.puts "Could not allocate a context or socket!"
22
- raise
23
- end
24
-
25
- assert(s.setsockopt(ZMQ::LINGER, 1_000))
26
- assert(s.connect(connect_to))
27
-
28
- contents = "#{'0'*message_size}"
29
-
30
- i = 0
31
- while i < message_count
32
- msg = ZMQ::Message.new(contents)
33
- assert(s.sendmsg(msg))
34
- i += 1
35
- end
36
-
37
- assert(s.close)
38
-
39
- ctx.terminate
@@ -1,74 +0,0 @@
1
-
2
- require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'ffi-rzmq')
3
-
4
- #if ARGV.length != 3
5
- # puts "usage: ruby local_throughtput.rb <bind-to> <message-size> <message-count>"
6
- # Process.exit
7
- #end
8
- p ZMQ::Util.version
9
-
10
- def assert(rc)
11
- raise "Last API call failed at #{caller(1)}" unless rc >= 0
12
- end
13
-
14
- bind_to = ARGV[0]
15
- message_size = ARGV[1].to_i
16
- message_count = ARGV[2].to_i
17
- sleep_time = ARGV[3].to_f
18
-
19
- begin
20
- ctx = ZMQ::Context.new
21
- s = ZMQ::Socket.new(ctx.pointer, ZMQ::SUB)
22
- rescue ContextError => e
23
- STDERR.puts "Failed to allocate context or socket!"
24
- raise
25
- end
26
-
27
- #assert(s.setsockopt(ZMQ::LINGER, 100))
28
- assert(s.setsockopt(ZMQ::IDENTITY, rand(999_999).to_s))
29
- assert(s.setsockopt(ZMQ::SUBSCRIBE, ""))
30
- assert(s.setsockopt(ZMQ::HWM, 1))
31
- #assert(s.setsockopt(ZMQ::RCVHWM, 0))
32
- #assert(s.setsockopt(ZMQ::SNDHWM, 0))
33
-
34
- assert(s.connect(bind_to))
35
- sleep 1
36
-
37
- msg = ZMQ::Message.new
38
- msg = ''
39
- assert(s.recv_string(msg))
40
- raise unless msg.to_i == 0
41
-
42
- start_time = Time.now
43
-
44
- i = 1
45
- while i < message_count - 1
46
- assert(s.recv_string(msg))
47
- msg_i = msg.to_i
48
- missed = (msg_i - i) - 1
49
- puts "missed [#{missed}] messages" if missed > 0
50
- i = msg_i
51
-
52
- start = Time.now
53
- while (Time.now - start) < sleep_time
54
- end
55
- end
56
-
57
- end_time = Time.now
58
-
59
- elapsed = (end_time.to_f - start_time.to_f) * 1000000
60
- if elapsed == 0
61
- elapsed = 1
62
- end
63
-
64
- throughput = message_count * 1000000 / elapsed
65
- megabits = throughput * message_size * 8 / 1000000
66
-
67
- puts "message size: %i [B]" % message_size
68
- puts "message count: %i" % message_count
69
- puts "mean throughput: %i [msg/s]" % throughput
70
- puts "mean throughput: %.3f [Mb/s]" % megabits
71
-
72
- assert(s.close)
73
-
74
- ctx.terminate
@@ -1,138 +0,0 @@
1
- require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'ffi-rzmq')
2
-
3
-
4
- # Within a single process, we start up five threads. Main thread has a PUB (publisher)
5
- # socket and the secondary threads have SUB (subscription) sockets. We measure the
6
- # *throughput* between these sockets. A high-water mark (HWM) is *not* set, so the
7
- # publisher queue is free to grow to the size of memory without dropping packets.
8
- #
9
- # This example also illustrates how a single context can be shared amongst several
10
- # threads. Sharing a single context also allows a user to specify the "inproc"
11
- # transport in addition to "tcp" and "ipc".
12
- #
13
- # % ruby throughput_measurement.rb tcp://127.0.0.1:5555 1024 1_000_000
14
- #
15
- # % ruby throughput_measurement.rb inproc://lm_sock 1024 1_000_000
16
- #
17
-
18
- if ARGV.length < 3
19
- puts "usage: ruby throughput_measurement.rb <connect-to> <message-size> <roundtrip-count>"
20
- exit
21
- end
22
-
23
- link = ARGV[0]
24
- message_size = ARGV[1].to_i
25
- count = ARGV[2].to_i
26
-
27
- def assert(rc)
28
- raise "Last API call failed at #{caller(1)}" unless rc >= 0
29
- end
30
-
31
- begin
32
- master_context = ZMQ::Context.new
33
- rescue ContextError => e
34
- STDERR.puts "Failed to allocate context or socket!"
35
- raise
36
- end
37
-
38
-
39
- class Receiver
40
- def initialize context, link, size, count
41
- @context = context
42
- @link = link
43
- @size = size
44
- @count = count
45
-
46
- begin
47
- @socket = @context.socket(ZMQ::SUB)
48
- rescue ContextError => e
49
- STDERR.puts "Failed to allocate SUB socket!"
50
- raise
51
- end
52
-
53
- assert(@socket.setsockopt(ZMQ::LINGER, 100))
54
- assert(@socket.setsockopt(ZMQ::SUBSCRIBE, ""))
55
-
56
- assert(@socket.connect(@link))
57
- end
58
-
59
- def run
60
- msg = ZMQ::Message.new
61
- assert(@socket.recvmsg(msg))
62
-
63
- elapsed = elapsed_microseconds do
64
- (@count -1).times do
65
- assert(@socket.recvmsg(msg))
66
- end
67
- end
68
-
69
- throughput = @count * 1000000 / elapsed
70
- megabits = throughput * @size * 8 / 1000000
71
-
72
- puts "message size: %i [B]" % @size
73
- puts "message count: %i" % @count
74
- puts "mean throughput: %i [msg/s]" % throughput
75
- puts "mean throughput: %.3f [Mb/s]" % megabits
76
-
77
- assert(@socket.close)
78
- end
79
-
80
- def elapsed_microseconds(&blk)
81
- start = Time.now
82
- yield
83
- ((Time.now - start) * 1_000_000)
84
- end
85
- end
86
-
87
- class Transmitter
88
- def initialize context, link, size, count
89
- @context = context
90
- @link = link
91
- @size = size
92
- @count = count
93
-
94
- begin
95
- @socket = @context.socket(ZMQ::PUB)
96
- rescue ContextError => e
97
- STDERR.puts "Failed to allocate PUB socket!"
98
- raise
99
- end
100
-
101
- assert(@socket.setsockopt(ZMQ::LINGER, 100))
102
-
103
- assert(@socket.bind(@link))
104
- end
105
-
106
- def run
107
- sleep 1
108
- contents = "#{'0' * @size}"
109
-
110
- i = 0
111
- while i < @count
112
- msg = ZMQ::Message.new(contents)
113
- assert(@socket.sendmsg(msg))
114
- i += 1
115
- end
116
-
117
- assert(@socket.close)
118
- end
119
- end
120
-
121
- threads = []
122
-
123
- threads << Thread.new do
124
- transmitter = Transmitter.new(master_context, link, message_size, count)
125
- transmitter.run
126
- end
127
-
128
- 1.times do
129
- threads << Thread.new do
130
- receiver = Receiver.new(master_context, link, message_size, count)
131
- receiver.run
132
- end
133
- end
134
-
135
-
136
- threads.each {|t| t.join}
137
-
138
- master_context.terminate
@@ -1,93 +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
-
12
- begin
13
- ctx = ZMQ::Context.new
14
- s1 = ctx.socket(ZMQ::XREQ)
15
- s2 = ctx.socket(ZMQ::XREP)
16
- rescue ContextError => e
17
- STDERR.puts "Failed to allocate context or socket"
18
- raise
19
- end
20
-
21
- s1.identity = 'socket1.xreq'
22
- s2.identity = 'socket2.xrep'
23
-
24
- assert(s1.setsockopt(ZMQ::LINGER, 100))
25
- assert(s2.setsockopt(ZMQ::LINGER, 100))
26
-
27
- assert(s1.bind(link))
28
- assert(s2.connect(link))
29
-
30
- poller = ZMQ::Poller.new
31
- poller.register_readable(s2)
32
- poller.register_writable(s1)
33
-
34
- start_time = Time.now
35
- @unsent = true
36
-
37
- until @done do
38
- assert(poller.poll_nonblock)
39
-
40
- # send the message after 5 seconds
41
- if Time.now - start_time > 5 && @unsent
42
- puts "sending payload nonblocking"
43
-
44
- 5.times do |i|
45
- payload = "#{ i.to_s * 40 }"
46
- assert(s1.send_string(payload, ZMQ::NonBlocking))
47
- end
48
- @unsent = false
49
- end
50
-
51
- # check for messages after 1 second
52
- if Time.now - start_time > 1
53
- poller.readables.each do |sock|
54
-
55
- if sock.identity =~ /xrep/
56
- routing_info = ''
57
- assert(sock.recv_string(routing_info, ZMQ::NonBlocking))
58
- puts "routing_info received [#{routing_info}] on socket.identity [#{sock.identity}]"
59
- else
60
- routing_info = nil
61
- received_msg = ''
62
- assert(sock.recv_string(received_msg, ZMQ::NonBlocking))
63
-
64
- # skip to the next iteration if received_msg is nil; that means we got an EAGAIN
65
- next unless received_msg
66
- puts "message received [#{received_msg}] on socket.identity [#{sock.identity}]"
67
- end
68
-
69
- while sock.more_parts? do
70
- received_msg = ''
71
- assert(sock.recv_string(received_msg, ZMQ::NonBlocking))
72
-
73
- puts "message received [#{received_msg}]"
74
- end
75
-
76
- puts "kick back a reply"
77
- assert(sock.send_string(routing_info, ZMQ::SNDMORE | ZMQ::NonBlocking)) if routing_info
78
- time = Time.now.strftime "%Y-%m-%dT%H:%M:%S.#{Time.now.usec}"
79
- reply = "reply " + sock.identity.upcase + " #{time}"
80
- puts "sent reply [#{reply}], #{time}"
81
- assert(sock.send_string(reply))
82
- @done = true
83
- poller.register_readable(s1)
84
- end
85
- end
86
- end
87
-
88
- puts "executed in [#{Time.now - start_time}] seconds"
89
-
90
- assert(s1.close)
91
- assert(s2.close)
92
-
93
- ctx.terminate