ffi-rzmq 0.9.3 → 0.9.6

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.
@@ -71,7 +71,7 @@ assert(s4.recv_string(body)) if s4.more_parts?
71
71
  puts "s4 received topic [#{topic}], body [#{body}]"
72
72
 
73
73
  s5_string = ''
74
- rc = s5.recv_string(s5_string, ZMQ::DONTWAIT)
74
+ rc = s5.recv_string(s5_string, ZMQ::NonBlocking)
75
75
  eagain = (rc == -1 && ZMQ::Util.errno == ZMQ::EAGAIN)
76
76
  puts(eagain ? "s5 received no messages" : "s5 FAILED")
77
77
 
@@ -38,7 +38,7 @@ until @done do
38
38
  payload = "#{ '3' * 1024 }"
39
39
 
40
40
  puts "sending payload nonblocking"
41
- assert(s1.send_string(payload, ZMQ::DONTWAIT))
41
+ assert(s1.send_string(payload, ZMQ::NonBlocking))
42
42
  @unsent = false
43
43
  end
44
44
 
@@ -46,7 +46,7 @@ until @done do
46
46
  if Time.now - start_time > 1
47
47
  poller.readables.each do |sock|
48
48
  received_msg = ''
49
- assert(sock.recv_string(received_msg, ZMQ::DONTWAIT))
49
+ assert(sock.recv_string(received_msg, ZMQ::NonBlocking))
50
50
 
51
51
  puts "message received [#{received_msg}]"
52
52
  @done = true
@@ -0,0 +1,69 @@
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::SUBSCRIBE, ""))
29
+ assert(s.setsockopt(ZMQ::RCVHWM, 20))
30
+ #assert(s.setsockopt(ZMQ::RCVHWM, 0))
31
+ #assert(s.setsockopt(ZMQ::SNDHWM, 0))
32
+
33
+ assert(s.connect(bind_to))
34
+ sleep 1
35
+
36
+ msg = ZMQ::Message.new
37
+ msg = ''
38
+ assert(s.recv_string(msg))
39
+ raise unless msg.to_i == 0
40
+
41
+ start_time = Time.now
42
+
43
+ i = 1
44
+ while i < message_count
45
+ assert(s.recv_string(msg))
46
+ msg_i = msg.to_i
47
+ puts "missed [#{msg_i - i}] messages"
48
+ i = msg_i
49
+ sleep(sleep_time)
50
+ end
51
+
52
+ end_time = Time.now
53
+
54
+ elapsed = (end_time.to_f - start_time.to_f) * 1000000
55
+ if elapsed == 0
56
+ elapsed = 1
57
+ end
58
+
59
+ throughput = message_count * 1000000 / elapsed
60
+ megabits = throughput * message_size * 8 / 1000000
61
+
62
+ puts "message size: %i [B]" % message_size
63
+ puts "message count: %i" % message_count
64
+ puts "mean throughput: %i [msg/s]" % throughput
65
+ puts "mean throughput: %.3f [Mb/s]" % megabits
66
+
67
+ assert(s.close)
68
+
69
+ ctx.terminate
@@ -43,7 +43,7 @@ until @done do
43
43
 
44
44
  5.times do |i|
45
45
  payload = "#{ i.to_s * 40 }"
46
- assert(s1.send_string(payload, ZMQ::DONTWAIT))
46
+ assert(s1.send_string(payload, ZMQ::NonBlocking))
47
47
  end
48
48
  @unsent = false
49
49
  end
@@ -54,12 +54,12 @@ until @done do
54
54
 
55
55
  if sock.identity =~ /xrep/
56
56
  routing_info = ''
57
- assert(sock.recv_string(routing_info, ZMQ::DONTWAIT))
57
+ assert(sock.recv_string(routing_info, ZMQ::NonBlocking))
58
58
  puts "routing_info received [#{routing_info}] on socket.identity [#{sock.identity}]"
59
59
  else
60
60
  routing_info = nil
61
61
  received_msg = ''
62
- assert(sock.recv_string(received_msg, ZMQ::DONTWAIT))
62
+ assert(sock.recv_string(received_msg, ZMQ::NonBlocking))
63
63
 
64
64
  # skip to the next iteration if received_msg is nil; that means we got an EAGAIN
65
65
  next unless received_msg
@@ -68,13 +68,13 @@ until @done do
68
68
 
69
69
  while sock.more_parts? do
70
70
  received_msg = ''
71
- assert(sock.recv_string(received_msg, ZMQ::DONTWAIT))
71
+ assert(sock.recv_string(received_msg, ZMQ::NonBlocking))
72
72
 
73
73
  puts "message received [#{received_msg}]"
74
74
  end
75
75
 
76
76
  puts "kick back a reply"
77
- assert(sock.send_string(routing_info, ZMQ::SNDMORE | ZMQ::DONTWAIT)) if routing_info
77
+ assert(sock.send_string(routing_info, ZMQ::SNDMORE | ZMQ::NonBlocking)) if routing_info
78
78
  time = Time.now.strftime "%Y-%m-%dT%H:%M:%S.#{Time.now.usec}"
79
79
  reply = "reply " + sock.identity.upcase + " #{time}"
80
80
  puts "sent reply [#{reply}], #{time}"
data/ffi-rzmq.gemspec CHANGED
@@ -6,12 +6,12 @@ Gem::Specification.new do |s|
6
6
  s.name = "ffi-rzmq"
7
7
  s.version = ZMQ::VERSION
8
8
  s.authors = ["Chuck Remes"]
9
- s.email = ["cremes@mac.com"]
9
+ s.email = ["git@chuckremes.com"]
10
10
  s.homepage = "http://github.com/chuckremes/ffi-rzmq"
11
11
  s.summary = %q{This gem wraps the ZeroMQ (0mq) networking library using Ruby FFI (foreign function interface).}
12
12
  s.description = %q{This gem wraps the ZeroMQ networking library using the ruby FFI (foreign
13
13
  function interface). It's a pure ruby wrapper so this gem can be loaded
14
- and run by any ruby runtime that supports FFI. That's all of them:
14
+ and run by any ruby runtime that supports FFI. That's all of them -
15
15
  MRI 1.9.x, Rubinius and JRuby.}
16
16
 
17
17
  s.rubyforge_project = "ffi-rzmq"
@@ -1,7 +1,7 @@
1
1
  module ZMQ
2
2
  # Set up all of the constants that are *common* to all API
3
3
  # versions
4
-
4
+
5
5
  # Socket types
6
6
  PAIR = 0
7
7
  PUB = 1
@@ -41,6 +41,8 @@ module ZMQ
41
41
  RECONNECT_IVL = 18
42
42
  BACKLOG = 19
43
43
  RECONNECT_IVL_MAX = 21
44
+ RCVTIMEO = 27
45
+ SNDTIMEO = 28
44
46
 
45
47
  # Send/recv options
46
48
  SNDMORE = 2
@@ -58,13 +60,14 @@ module ZMQ
58
60
  ENOMEM = Errno::ENOMEM::Errno
59
61
  ENODEV = Errno::ENODEV::Errno
60
62
  EFAULT = Errno::EFAULT::Errno
63
+ EINTR = Errno::EINTR::Errno
61
64
 
62
65
  # ZMQ errors
63
66
  HAUSNUMERO = 156384712
64
- EMTHREAD = (HAUSNUMERO + 50)
65
67
  EFSM = (HAUSNUMERO + 51)
66
68
  ENOCOMPATPROTO = (HAUSNUMERO + 52)
67
69
  ETERM = (HAUSNUMERO + 53)
70
+ EMTHREAD = (HAUSNUMERO + 54)
68
71
 
69
72
  # Rescue unknown constants and use the ZeroMQ defined values
70
73
  # Usually only happens on Windows though some don't resolve on
@@ -78,7 +81,20 @@ module ZMQ
78
81
  ECONNREFUSED = Errno::ECONNREFUSED::Errno rescue (HAUSNUMERO + 7)
79
82
  EINPROGRESS = Errno::EINPROGRESS::Errno rescue (HAUSNUMERO + 8)
80
83
  ENOTSOCK = Errno::ENOTSOCK::Errno rescue (HAUSNUMERO + 9)
81
- EINTR = Errno::EINTR::Errno rescue (HAUSNUMERO + 10)
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
82
98
  end # module ZMQ
83
99
 
84
100
 
@@ -93,11 +109,6 @@ if ZMQ::LibZMQ.version2?
93
109
  SocketTypeNameMap[ROUTER] = 'ROUTER'
94
110
  SocketTypeNameMap[DEALER] = 'DEALER'
95
111
 
96
- # Device Types
97
- STREAMER = 1
98
- FORWARDER = 2
99
- QUEUE = 3
100
-
101
112
  # Socket options
102
113
  HWM = 1
103
114
  IDENTITY = 5
@@ -107,6 +118,7 @@ if ZMQ::LibZMQ.version2?
107
118
 
108
119
  # Send/recv options
109
120
  NOBLOCK = 1
121
+ NonBlocking = NOBLOCK
110
122
  end
111
123
  end # version2?
112
124
 
@@ -124,22 +136,48 @@ if ZMQ::LibZMQ.version3?
124
136
  SocketTypeNameMap[XPUB] = 'XPUB'
125
137
  SocketTypeNameMap[XSUB] = 'XSUB'
126
138
 
139
+ # Context options
140
+ IO_THREADS = 1
141
+ MAX_SOCKETS = 2
142
+ IO_THREADS_DFLT = 1
143
+ MAX_SOCKETS_DFLT = 1024
144
+
127
145
  # Socket options
128
- IDENTITY = 5
129
- MAXMSGSIZE = 22
130
- SNDHWM = 23
131
- RCVHWM = 24
146
+ IDENTITY = 5
147
+ MAXMSGSIZE = 22
148
+ SNDHWM = 23
149
+ RCVHWM = 24
132
150
  MULTICAST_HOPS = 25
133
- RCVTIMEO = 27
134
- SNDTIMEO = 28
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
135
162
 
136
163
  # Send/recv options
137
- DONTWAIT = 1
138
- SNDLABEL = 4
139
-
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
140
179
 
141
180
  # Socket & other errors
142
181
  EMFILE = Errno::EMFILE::Errno
143
-
144
182
  end
145
183
  end # version3?
@@ -3,9 +3,9 @@ module ZMQ
3
3
 
4
4
 
5
5
  # Recommended to use the default for +io_threads+
6
- # since most programs will not saturate I/O.
6
+ # since most programs will not saturate I/O.
7
7
  #
8
- # The rule of thumb is to make +io_threads+ equal to the number
8
+ # The rule of thumb is to make +io_threads+ equal to the number
9
9
  # gigabits per second that the application will produce.
10
10
  #
11
11
  # The +io_threads+ number specifies the size of the thread pool
@@ -41,23 +41,50 @@ module ZMQ
41
41
  #
42
42
  #
43
43
  class Context
44
- include ZMQ::Util
45
44
 
46
- attr_reader :context, :pointer
45
+ attr_reader :context, :io_threads, :max_sockets
46
+ alias :pointer :context
47
47
 
48
- def self.create io_threads = 1
49
- new(io_threads) rescue nil
50
- end
51
-
52
48
  # Use the factory method Context#create to make contexts.
53
49
  #
54
- def initialize io_threads = 1
55
- @sockets = []
56
- @context = LibZMQ.zmq_init io_threads
57
- @pointer = @context
58
- error_check 'zmq_init', (@context.nil? || @context.null?) ? -1 : 0
50
+ if LibZMQ.version2?
51
+ def self.create io_threads = 1
52
+ new(io_threads) rescue nil
53
+ end
54
+
55
+ def initialize io_threads = 1
56
+ @io_threads = io_threads
57
+ @context = LibZMQ.zmq_init io_threads
58
+ ZMQ::Util.error_check 'zmq_init', (@context.nil? || @context.null?) ? -1 : 0
59
+
60
+ define_finalizer
61
+ end
62
+ elsif LibZMQ.version3?
63
+
64
+ def self.create(opts = {})
65
+ new(opts) rescue nil
66
+ end
59
67
 
60
- define_finalizer
68
+ def initialize(opts = {})
69
+ if opts.respond_to?(:empty?)
70
+ @io_threads = opts[:io_threads] || IO_THREADS_DFLT
71
+ @max_sockets = opts[:max_sockets] || MAX_SOCKETS_DFLT
72
+ else
73
+ @io_threads = opts || 1
74
+ @max_sockets = MAX_SOCKETS_DFLT
75
+ end
76
+
77
+ @context = LibZMQ.zmq_ctx_new
78
+ ZMQ::Util.error_check 'zmq_ctx_new', (@context.nil? || @context.null?) ? -1 : 0
79
+
80
+ rc = LibZMQ.zmq_ctx_set(@context, ZMQ::IO_THREADS, @io_threads)
81
+ ZMQ::Util.error_check 'zmq_ctx_set', rc
82
+
83
+ rc = LibZMQ.zmq_ctx_set(@context, ZMQ::MAX_SOCKETS, @max_sockets)
84
+ ZMQ::Util.error_check 'zmq_ctx_set', rc
85
+
86
+ define_finalizer
87
+ end
61
88
  end
62
89
 
63
90
  # Call to release the context and any remaining data associated
@@ -67,15 +94,27 @@ module ZMQ
67
94
  #
68
95
  # Returns 0 for success, -1 for failure.
69
96
  #
70
- def terminate
71
- unless @context.nil? || @context.null?
72
- remove_finalizer
73
- rc = LibZMQ.zmq_term @context
74
- @context = nil
75
- @sockets = nil
76
- rc
77
- else
78
- 0
97
+ if LibZMQ.version2?
98
+ def terminate
99
+ unless @context.nil? || @context.null?
100
+ remove_finalizer
101
+ rc = LibZMQ.zmq_term @context
102
+ @context = nil
103
+ rc
104
+ else
105
+ 0
106
+ end
107
+ end
108
+ elsif LibZMQ.version3?
109
+ def terminate
110
+ unless @context.nil? || @context.null?
111
+ remove_finalizer
112
+ rc = LibZMQ.zmq_ctx_destroy(@context)
113
+ @context = nil
114
+ rc
115
+ else
116
+ 0
117
+ end
79
118
  end
80
119
  end
81
120
 
@@ -102,7 +141,7 @@ module ZMQ
102
141
  rescue ContextError => e
103
142
  sock = nil
104
143
  end
105
-
144
+
106
145
  sock
107
146
  end
108
147
 
@@ -1,28 +1,28 @@
1
1
  module ZMQ
2
- if LibZMQ.version2?
3
- class Device
4
- attr_reader :device
5
-
6
- def self.create(device_type, frontend, backend)
2
+
3
+ class Device
4
+ attr_reader :device
5
+
6
+ def self.create(device_type, frontend, backend)
7
+ dev = nil
8
+ begin
9
+ dev = new(device_type, frontend, backend)
10
+ rescue ArgumentError
7
11
  dev = nil
8
- begin
9
- dev = new device_type, frontend, backend
10
- rescue ArgumentError
11
- dev = nil
12
- end
13
-
14
- dev
15
12
  end
16
13
 
17
- def initialize(device_type,frontend,backend)
18
- [["frontend", frontend],["backend", backend]].each do |name,socket|
19
- unless socket.is_a?(ZMQ::Socket)
20
- raise ArgumentError, "Expected a ZMQ::Socket, not a #{socket.class} as the #{name}"
21
- end
22
- end
14
+ dev
15
+ end
23
16
 
24
- LibZMQ.zmq_device(device_type, frontend.socket, backend.socket)
17
+ def initialize(device_type, frontend, backend)
18
+ [["frontend", frontend], ["backend", backend]].each do |name, socket|
19
+ unless socket.is_a?(ZMQ::Socket)
20
+ raise ArgumentError, "Expected a ZMQ::Socket, not a #{socket.class} as the #{name}"
21
+ end
25
22
  end
23
+
24
+ LibZMQ.zmq_device(device_type, frontend.socket, backend.socket)
26
25
  end
27
26
  end
27
+
28
28
  end