ffi-rzmq 1.0.3 → 2.0.4

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 (59) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +1 -1
  3. data/AUTHORS.txt +5 -1
  4. data/History.txt +45 -0
  5. data/README.rdoc +58 -28
  6. data/Rakefile +15 -0
  7. data/examples/README.rdoc +1 -3
  8. data/examples/{v3api/latency_measurement.rb → latency_measurement.rb} +1 -2
  9. data/examples/{v3api/local_lat.rb → local_lat.rb} +1 -1
  10. data/examples/{v3api/local_lat_poll.rb → local_lat_poll.rb} +4 -4
  11. data/examples/{v3api/local_throughput.rb → local_throughput.rb} +1 -1
  12. data/examples/{v3api/pub.rb → pub.rb} +1 -1
  13. data/examples/{v2api/publish_subscribe.rb → publish_subscribe.rb} +2 -2
  14. data/examples/{v2api/remote_lat.rb → remote_lat.rb} +1 -1
  15. data/examples/{v3api/remote_throughput.rb → remote_throughput.rb} +4 -3
  16. data/examples/repreq_over_curve.rb +60 -0
  17. data/examples/{v2api/reqrep_poll.rb → reqrep_poll.rb} +3 -4
  18. data/examples/{v2api/request_response.rb → request_response.rb} +1 -2
  19. data/examples/{v3api/sub.rb → sub.rb} +1 -2
  20. data/examples/{v3api/throughput_measurement.rb → throughput_measurement.rb} +1 -1
  21. data/examples/{v3api/xreqxrep_poll.rb → xreqxrep_poll.rb} +6 -7
  22. data/ffi-rzmq.gemspec +4 -4
  23. data/lib/ffi-rzmq.rb +2 -3
  24. data/lib/ffi-rzmq/context.rb +25 -53
  25. data/lib/ffi-rzmq/device.rb +8 -4
  26. data/lib/ffi-rzmq/exceptions.rb +3 -0
  27. data/lib/ffi-rzmq/message.rb +24 -30
  28. data/lib/ffi-rzmq/poll.rb +5 -16
  29. data/lib/ffi-rzmq/socket.rb +132 -282
  30. data/lib/ffi-rzmq/util.rb +28 -36
  31. data/lib/ffi-rzmq/version.rb +1 -1
  32. data/spec/context_spec.rb +18 -23
  33. data/spec/device_spec.rb +13 -12
  34. data/spec/message_spec.rb +13 -13
  35. data/spec/multipart_spec.rb +11 -11
  36. data/spec/nonblocking_recv_spec.rb +22 -22
  37. data/spec/poll_spec.rb +49 -49
  38. data/spec/pushpull_spec.rb +12 -11
  39. data/spec/reqrep_spec.rb +11 -11
  40. data/spec/socket_spec.rb +109 -196
  41. data/spec/spec_helper.rb +3 -11
  42. data/spec/util_spec.rb +29 -0
  43. metadata +80 -104
  44. data/examples/v2api/latency_measurement.rb +0 -139
  45. data/examples/v2api/local_lat.rb +0 -58
  46. data/examples/v2api/local_lat_poll.rb +0 -66
  47. data/examples/v2api/local_throughput.rb +0 -58
  48. data/examples/v2api/pub.rb +0 -46
  49. data/examples/v2api/remote_throughput.rb +0 -39
  50. data/examples/v2api/sub.rb +0 -74
  51. data/examples/v2api/throughput_measurement.rb +0 -138
  52. data/examples/v2api/xreqxrep_poll.rb +0 -93
  53. data/examples/v3api/publish_subscribe.rb +0 -82
  54. data/examples/v3api/remote_lat.rb +0 -71
  55. data/examples/v3api/reqrep_poll.rb +0 -62
  56. data/examples/v3api/request_response.rb +0 -40
  57. data/lib/ffi-rzmq/constants.rb +0 -187
  58. data/lib/ffi-rzmq/libc.rb +0 -19
  59. data/lib/ffi-rzmq/libzmq.rb +0 -283
@@ -1,6 +1,5 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'ffi-rzmq')
3
-
2
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'ffi-rzmq')
4
3
 
5
4
  def assert(rc)
6
5
  raise "Last API call failed at #{caller(1)}" unless rc >= 0
@@ -38,7 +37,7 @@ until @done do
38
37
  payload = "#{ '3' * 1024 }"
39
38
 
40
39
  puts "sending payload nonblocking"
41
- assert(s1.send_string(payload, ZMQ::NonBlocking))
40
+ assert(s1.send_string(payload, ZMQ::DONTWAIT))
42
41
  @unsent = false
43
42
  end
44
43
 
@@ -46,7 +45,7 @@ until @done do
46
45
  if Time.now - start_time > 1
47
46
  poller.readables.each do |sock|
48
47
  received_msg = ''
49
- assert(sock.recv_string(received_msg, ZMQ::NonBlocking))
48
+ assert(sock.recv_string(received_msg, ZMQ::DONTWAIT))
50
49
 
51
50
  puts "message received [#{received_msg}]"
52
51
  @done = true
@@ -1,6 +1,5 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'ffi-rzmq')
3
-
2
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'ffi-rzmq')
4
3
 
5
4
  def assert(rc)
6
5
  raise "Last API call failed at #{caller(1)}" unless rc >= 0
@@ -1,11 +1,10 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'ffi-rzmq')
2
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'ffi-rzmq')
3
3
 
4
4
  #if ARGV.length != 3
5
5
  # puts "usage: ruby local_throughtput.rb <bind-to> <message-size> <message-count>"
6
6
  # Process.exit
7
7
  #end
8
- p ZMQ::Util.version
9
8
 
10
9
  def assert(rc)
11
10
  raise "Last API call failed at #{caller(1)}" unless rc >= 0
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'ffi-rzmq')
1
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'ffi-rzmq')
2
2
  require 'thread'
3
3
 
4
4
  # Within a single process, we start up five threads. Main thread has a PUB (publisher)
@@ -1,6 +1,5 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'ffi-rzmq')
3
-
2
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'ffi-rzmq')
4
3
 
5
4
  def assert(rc)
6
5
  raise "Last API call failed at #{caller(1)}" unless rc >= 0
@@ -43,7 +42,7 @@ until @done do
43
42
 
44
43
  5.times do |i|
45
44
  payload = "#{ i.to_s * 40 }"
46
- assert(s1.send_string(payload, ZMQ::NonBlocking))
45
+ assert(s1.send_string(payload, ZMQ::DONTWAIT))
47
46
  end
48
47
  @unsent = false
49
48
  end
@@ -54,12 +53,12 @@ until @done do
54
53
 
55
54
  if sock.identity =~ /xrep/
56
55
  routing_info = ''
57
- assert(sock.recv_string(routing_info, ZMQ::NonBlocking))
56
+ assert(sock.recv_string(routing_info, ZMQ::DONTWAIT))
58
57
  puts "routing_info received [#{routing_info}] on socket.identity [#{sock.identity}]"
59
58
  else
60
59
  routing_info = nil
61
60
  received_msg = ''
62
- assert(sock.recv_string(received_msg, ZMQ::NonBlocking))
61
+ assert(sock.recv_string(received_msg, ZMQ::DONTWAIT))
63
62
 
64
63
  # skip to the next iteration if received_msg is nil; that means we got an EAGAIN
65
64
  next unless received_msg
@@ -68,13 +67,13 @@ until @done do
68
67
 
69
68
  while sock.more_parts? do
70
69
  received_msg = ''
71
- assert(sock.recv_string(received_msg, ZMQ::NonBlocking))
70
+ assert(sock.recv_string(received_msg, ZMQ::DONTWAIT))
72
71
 
73
72
  puts "message received [#{received_msg}]"
74
73
  end
75
74
 
76
75
  puts "kick back a reply"
77
- assert(sock.send_string(routing_info, ZMQ::SNDMORE | ZMQ::NonBlocking)) if routing_info
76
+ assert(sock.send_string(routing_info, ZMQ::SNDMORE | ZMQ::DONTWAIT)) if routing_info
78
77
  time = Time.now.strftime "%Y-%m-%dT%H:%M:%S.#{Time.now.usec}"
79
78
  reply = "reply " + sock.identity.upcase + " #{time}"
80
79
  puts "sent reply [#{reply}], #{time}"
data/ffi-rzmq.gemspec CHANGED
@@ -11,9 +11,9 @@ Gem::Specification.new do |s|
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 the major ones -
15
- MRI, Rubinius and JRuby.}
14
+ and run by any ruby runtime that supports FFI. That's all of the major ones - MRI, Rubinius and JRuby.}
16
15
 
16
+ s.license = 'MIT'
17
17
  s.rubyforge_project = "ffi-rzmq"
18
18
 
19
19
  s.files = `git ls-files`.split("\n")
@@ -21,7 +21,7 @@ MRI, Rubinius and JRuby.}
21
21
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
22
  s.require_paths = ["lib"]
23
23
 
24
- s.add_runtime_dependency "ffi"#, [">= 1.0.9"]
25
- s.add_development_dependency "rspec", ["~> 2.6"]
24
+ s.add_runtime_dependency "ffi-rzmq-core", [">= 1.0.1"]
25
+ s.add_development_dependency "rspec", ["~> 2.14"]
26
26
  s.add_development_dependency "rake"
27
27
  end
data/lib/ffi-rzmq.rb CHANGED
@@ -63,10 +63,9 @@ end # module ZMQ
63
63
  # some code is conditionalized based upon what ruby engine we are
64
64
  # executing
65
65
 
66
- require 'ffi'
66
+ require 'ffi-rzmq-core'
67
67
 
68
68
  # the order of files is important
69
- #%w(wrapper zmq exceptions context message socket poll_items poll device).each do |file|
70
- %w(libc libzmq constants util exceptions context message socket poll_items poll_item poll device).each do |file|
69
+ %w(util exceptions context message socket poll_items poll_item poll device version).each do |file|
71
70
  require ZMQ.libpath(['ffi-rzmq', file])
72
71
  end
@@ -47,44 +47,29 @@ module ZMQ
47
47
 
48
48
  # Use the factory method Context#create to make contexts.
49
49
  #
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?
50
+ def self.create(opts = {})
51
+ new(opts) rescue nil
52
+ end
63
53
 
64
- def self.create(opts = {})
65
- new(opts) rescue nil
54
+ def initialize(opts = {})
55
+ if opts.respond_to?(:empty?)
56
+ @io_threads = opts[:io_threads] || IO_THREADS_DFLT
57
+ @max_sockets = opts[:max_sockets] || MAX_SOCKETS_DFLT
58
+ else
59
+ @io_threads = opts || 1
60
+ @max_sockets = MAX_SOCKETS_DFLT
66
61
  end
67
62
 
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
63
+ @context = LibZMQ.zmq_ctx_new
64
+ ZMQ::Util.error_check 'zmq_ctx_new', (@context.nil? || @context.null?) ? -1 : 0
79
65
 
80
- rc = LibZMQ.zmq_ctx_set(@context, ZMQ::IO_THREADS, @io_threads)
81
- ZMQ::Util.error_check 'zmq_ctx_set', rc
66
+ rc = LibZMQ.zmq_ctx_set(@context, ZMQ::IO_THREADS, @io_threads)
67
+ ZMQ::Util.error_check 'zmq_ctx_set', rc
82
68
 
83
- rc = LibZMQ.zmq_ctx_set(@context, ZMQ::MAX_SOCKETS, @max_sockets)
84
- ZMQ::Util.error_check 'zmq_ctx_set', rc
69
+ rc = LibZMQ.zmq_ctx_set(@context, ZMQ::MAX_SOCKETS, @max_sockets)
70
+ ZMQ::Util.error_check 'zmq_ctx_set', rc
85
71
 
86
- define_finalizer
87
- end
72
+ define_finalizer
88
73
  end
89
74
 
90
75
  # Call to release the context and any remaining data associated
@@ -94,27 +79,14 @@ module ZMQ
94
79
  #
95
80
  # Returns 0 for success, -1 for failure.
96
81
  #
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
82
+ def terminate
83
+ unless @context.nil? || @context.null?
84
+ remove_finalizer
85
+ rc = LibZMQ.zmq_ctx_destroy(@context)
86
+ @context = nil
87
+ rc
88
+ else
89
+ 0
118
90
  end
119
91
  end
120
92
 
@@ -3,10 +3,10 @@ module ZMQ
3
3
  class Device
4
4
  attr_reader :device
5
5
 
6
- def self.create(device_type, frontend, backend)
6
+ def self.create(frontend, backend, capture=nil)
7
7
  dev = nil
8
8
  begin
9
- dev = new(device_type, frontend, backend)
9
+ dev = new(frontend, backend, capture)
10
10
  rescue ArgumentError
11
11
  dev = nil
12
12
  end
@@ -14,15 +14,19 @@ module ZMQ
14
14
  dev
15
15
  end
16
16
 
17
- def initialize(device_type, frontend, backend)
17
+ def initialize(frontend, backend, capture=nil)
18
18
  [["frontend", frontend], ["backend", backend]].each do |name, socket|
19
19
  unless socket.is_a?(ZMQ::Socket)
20
20
  raise ArgumentError, "Expected a ZMQ::Socket, not a #{socket.class} as the #{name}"
21
21
  end
22
22
  end
23
23
 
24
- LibZMQ.zmq_device(device_type, frontend.socket, backend.socket)
24
+ LibZMQ.zmq_proxy(frontend.socket, backend.socket, capture ? capture.socket : nil)
25
25
  end
26
26
  end
27
+
28
+ # Alias for Device
29
+ #
30
+ class Proxy < Device; end
27
31
 
28
32
  end
@@ -13,6 +13,9 @@ module ZMQ
13
13
  end
14
14
  end # call ZeroMQError
15
15
 
16
+ class NotSupportedError < ZeroMQError
17
+ end
18
+
16
19
 
17
20
  class ContextError < ZeroMQError
18
21
  # True when the exception was raised due to the library
@@ -84,8 +84,8 @@ module ZMQ
84
84
  # puts "value1 is #{message.value1}"
85
85
  #
86
86
  class Message
87
-
88
- # Recommended way to create a standard message. A Message object is
87
+
88
+ # Recommended way to create a standard message. A Message object is
89
89
  # returned upon success, nil when allocation fails.
90
90
  #
91
91
  def self.create message = nil
@@ -129,7 +129,7 @@ module ZMQ
129
129
  data_buffer.write_string bytes, len
130
130
 
131
131
  # use libC to call free on the data buffer; earlier versions used an
132
- # FFI::Function here that called back into Ruby, but Rubinius won't
132
+ # FFI::Function here that called back into Ruby, but Rubinius won't
133
133
  # support that and there are issues with the other runtimes too
134
134
  LibZMQ.zmq_msg_init_data @pointer, data_buffer, len, LibC::Free, nil
135
135
  end
@@ -182,42 +182,36 @@ module ZMQ
182
182
  #
183
183
  def close
184
184
  rc = 0
185
-
185
+
186
186
  if @pointer
187
187
  rc = LibZMQ.zmq_msg_close @pointer
188
188
  @pointer = nil
189
189
  end
190
-
190
+
191
191
  rc
192
192
  end
193
-
193
+
194
194
  # cache the msg size so we don't have to recalculate it when creating
195
195
  # each new instance
196
- @msg_size = LibZMQ::Msg.size
197
-
196
+ @msg_size = LibZMQ::Message.size
197
+
198
198
  def self.msg_size() @msg_size; end
199
199
 
200
200
  end # class Message
201
-
202
- if LibZMQ.version3?
203
- class Message
204
- # Version3 only
205
- #
206
- def get(property)
207
- LibZMQ.zmq_msg_get(@pointer, property)
208
- end
209
-
210
- # Version3 only
211
- #
212
- # Returns true if this message has additional parts coming.
213
- #
214
- def more?
215
- Util.resultcode_ok?(get(MORE))
216
- end
217
-
218
- def set(property, value)
219
- LibZMQ.zmq_msg_set(@pointer, property, value)
220
- end
201
+
202
+ class Message
203
+ def get(property)
204
+ LibZMQ.zmq_msg_get(@pointer, property)
205
+ end
206
+
207
+ # Returns true if this message has additional parts coming.
208
+ #
209
+ def more?
210
+ Util.resultcode_ok?(get(MORE))
211
+ end
212
+
213
+ def set(property, value)
214
+ LibZMQ.zmq_msg_set(@pointer, property, value)
221
215
  end
222
216
  end
223
217
 
@@ -254,7 +248,7 @@ module ZMQ
254
248
  #
255
249
  def copy_in_bytes bytes, len
256
250
  rc = super(bytes, len)
257
-
251
+
258
252
  # make sure we have a way to deallocate this memory if the object goes
259
253
  # out of scope
260
254
  define_finalizer
@@ -296,7 +290,7 @@ module ZMQ
296
290
  # cache the msg size so we don't have to recalculate it when creating
297
291
  # each new instance
298
292
  # need to do this again because ivars are not inheritable
299
- @msg_size = LibZMQ::Msg.size
293
+ @msg_size = LibZMQ::Message.size
300
294
 
301
295
  end # class ManagedMessage
302
296
 
data/lib/ffi-rzmq/poll.rb CHANGED
@@ -150,22 +150,11 @@ module ZMQ
150
150
  # milliseconds, so we need to convert that value to
151
151
  # microseconds for the library.
152
152
  #
153
- if LibZMQ.version2?
154
- def adjust timeout
155
- if :blocking == timeout || -1 == timeout
156
- -1
157
- else
158
- (timeout * 1000).to_i
159
- end
160
- end
161
- else
162
- # version3 changed units from microseconds to milliseconds
163
- def adjust timeout
164
- if :blocking == timeout || -1 == timeout
165
- -1
166
- else
167
- timeout.to_i
168
- end
153
+ def adjust timeout
154
+ if :blocking == timeout || -1 == timeout
155
+ -1
156
+ else
157
+ timeout.to_i
169
158
  end
170
159
  end
171
160
 
@@ -1,8 +1,7 @@
1
1
 
2
2
  module ZMQ
3
3
 
4
- module CommonSocketBehavior
5
-
4
+ class Socket
6
5
  attr_reader :socket, :name
7
6
 
8
7
  # Allocates a socket of type +type+ for sending and receiving data.
@@ -70,15 +69,15 @@ module ZMQ
70
69
 
71
70
  context_ptr = context_ptr.pointer if context_ptr.kind_of?(ZMQ::Context)
72
71
 
73
- unless context_ptr.null?
72
+ if context_ptr.nil? || context_ptr.null?
73
+ raise ContextError.new 'zmq_socket', 0, ETERM, "Context pointer was null"
74
+ else
74
75
  @socket = LibZMQ.zmq_socket context_ptr, type
75
76
  if @socket && !@socket.null?
76
77
  @name = SocketTypeNameMap[type]
77
78
  else
78
79
  raise ContextError.new 'zmq_socket', 0, ETERM, "Socket pointer was null"
79
80
  end
80
- else
81
- raise ContextError.new 'zmq_socket', 0, ETERM, "Context pointer was null"
82
81
  end
83
82
 
84
83
  @longlong_cache = @int_cache = nil
@@ -118,7 +117,7 @@ module ZMQ
118
117
  # Returns 0 when the operation completed successfully.
119
118
  # Returns -1 when this operation failed.
120
119
  #
121
- # With a -1 return code, the user must check ZMQ.errno to determine the
120
+ # With a -1 return code, the user must check ZMQ::Util.errno to determine the
122
121
  # cause.
123
122
  #
124
123
  # rc = socket.setsockopt(ZMQ::LINGER, 1_000)
@@ -136,15 +135,14 @@ module ZMQ
136
135
  pointer.write_int value
137
136
 
138
137
  elsif 2 == @option_lookup[name]
138
+ # Strings are treated as pointers by FFI so we'll just pass it through
139
139
  length ||= value.size
140
+ pointer = value
140
141
 
141
- # note: not checking errno for failed memory allocations :(
142
- pointer = LibC.malloc length
143
- pointer.write_string value
144
142
  end
145
143
 
146
144
  rc = LibZMQ.zmq_setsockopt @socket, name, pointer, length
147
- LibC.free(pointer) unless pointer.nil? || pointer.null?
145
+ LibC.free(pointer) unless pointer.is_a?(String) || pointer.nil? || pointer.null?
148
146
  rc
149
147
  end
150
148
 
@@ -193,7 +191,7 @@ module ZMQ
193
191
  # depending upon the value of the socket option ZMQ::LINGER.
194
192
  #
195
193
  # Returns 0 upon success *or* when the socket has already been closed.
196
- # Returns -1 when the operation fails. Check ZMQ.errno for the error code.
194
+ # Returns -1 when the operation fails. Check ZMQ::Util.errno for the error code.
197
195
  #
198
196
  # rc = socket.close
199
197
  # puts("Given socket was invalid!") unless 0 == rc
@@ -215,15 +213,15 @@ module ZMQ
215
213
  #
216
214
  # +flags+ may take two values:
217
215
  # * 0 (default) - blocking operation
218
- # * ZMQ::NonBlocking - non-blocking operation
216
+ # * ZMQ::DONTWAIT - non-blocking operation
219
217
  # * ZMQ::SNDMORE - this message is part of a multi-part message
220
218
  #
221
219
  # Returns 0 when the message was successfully enqueued.
222
220
  # Returns -1 under two conditions.
223
221
  # 1. The message could not be enqueued
224
- # 2. When +flags+ is set with ZMQ::NonBlocking and the socket returned EAGAIN.
222
+ # 2. When +flags+ is set with ZMQ::DONTWAIT and the socket returned EAGAIN.
225
223
  #
226
- # With a -1 return code, the user must check ZMQ.errno to determine the
224
+ # With a -1 return code, the user must check ZMQ::Util.errno to determine the
227
225
  # cause.
228
226
  #
229
227
  def sendmsg message, flags = 0
@@ -233,14 +231,14 @@ module ZMQ
233
231
  # Helper method to make a new #Message instance out of the +string+ passed
234
232
  # in for transmission.
235
233
  #
236
- # +flags+ may be ZMQ::NonBlocking and ZMQ::SNDMORE.
234
+ # +flags+ may be ZMQ::DONTWAIT and ZMQ::SNDMORE.
237
235
  #
238
236
  # Returns 0 when the message was successfully enqueued.
239
237
  # Returns -1 under two conditions.
240
238
  # 1. The message could not be enqueued
241
- # 2. When +flags+ is set with ZMQ::NonBlocking and the socket returned EAGAIN.
239
+ # 2. When +flags+ is set with ZMQ::DONTWAIT and the socket returned EAGAIN.
242
240
  #
243
- # With a -1 return code, the user must check ZMQ.errno to determine the
241
+ # With a -1 return code, the user must check ZMQ::Util.errno to determine the
244
242
  # cause.
245
243
  #
246
244
  def send_string string, flags = 0
@@ -252,14 +250,14 @@ module ZMQ
252
250
  # passed in for transmission. Every element of +parts+ should be
253
251
  # a String.
254
252
  #
255
- # +flags+ may be ZMQ::NonBlocking.
253
+ # +flags+ may be ZMQ::DONTWAIT.
256
254
  #
257
255
  # Returns 0 when the messages were successfully enqueued.
258
256
  # Returns -1 under two conditions.
259
257
  # 1. A message could not be enqueued
260
- # 2. When +flags+ is set with ZMQ::NonBlocking and the socket returned EAGAIN.
258
+ # 2. When +flags+ is set with ZMQ::DONTWAIT and the socket returned EAGAIN.
261
259
  #
262
- # With a -1 return code, the user must check ZMQ.errno to determine the
260
+ # With a -1 return code, the user must check ZMQ::Util.errno to determine the
263
261
  # cause.
264
262
  #
265
263
  def send_strings parts, flags = 0
@@ -270,14 +268,14 @@ module ZMQ
270
268
  # passed in for transmission. Every element of +parts+ should be
271
269
  # a Message (or subclass).
272
270
  #
273
- # +flags+ may be ZMQ::NonBlocking.
271
+ # +flags+ may be ZMQ::DONTWAIT.
274
272
  #
275
273
  # Returns 0 when the messages were successfully enqueued.
276
274
  # Returns -1 under two conditions.
277
275
  # 1. A message could not be enqueued
278
- # 2. When +flags+ is set with ZMQ::NonBlocking and the socket returned EAGAIN.
276
+ # 2. When +flags+ is set with ZMQ::DONTWAIT and the socket returned EAGAIN.
279
277
  #
280
- # With a -1 return code, the user must check ZMQ.errno to determine the
278
+ # With a -1 return code, the user must check ZMQ::Util.errno to determine the
281
279
  # cause.
282
280
  #
283
281
  def sendmsgs parts, flags = 0
@@ -290,9 +288,9 @@ module ZMQ
290
288
  # Returns 0 when the message was successfully enqueued.
291
289
  # Returns -1 under two conditions.
292
290
  # 1. The message could not be enqueued
293
- # 2. When +flags+ is set with ZMQ::NonBlocking and the socket returned EAGAIN.
291
+ # 2. When +flags+ is set with ZMQ::DONTWAIT and the socket returned EAGAIN.
294
292
  #
295
- # With a -1 return code, the user must check ZMQ.errno to determine the
293
+ # With a -1 return code, the user must check ZMQ::Util.errno to determine the
296
294
  # cause.
297
295
  #
298
296
  def send_and_close message, flags = 0
@@ -305,14 +303,14 @@ module ZMQ
305
303
  #
306
304
  # +flags+ may take two values:
307
305
  # 0 (default) - blocking operation
308
- # ZMQ::NonBlocking - non-blocking operation
306
+ # ZMQ::DONTWAIT - non-blocking operation
309
307
  #
310
308
  # Returns 0 when the message was successfully dequeued.
311
309
  # Returns -1 under two conditions.
312
310
  # 1. The message could not be dequeued
313
- # 2. When +flags+ is set with ZMQ::NonBlocking and the socket returned EAGAIN.
311
+ # 2. When +flags+ is set with ZMQ::DONTWAIT and the socket returned EAGAIN.
314
312
  #
315
- # With a -1 return code, the user must check ZMQ.errno to determine the
313
+ # With a -1 return code, the user must check ZMQ::Util.errno to determine the
316
314
  # cause.
317
315
  #
318
316
  # The application code is responsible for handling the +message+ object lifecycle
@@ -326,14 +324,14 @@ module ZMQ
326
324
  # Helper method to make a new #Message instance and convert its payload
327
325
  # to a string.
328
326
  #
329
- # +flags+ may be ZMQ::NonBlocking.
327
+ # +flags+ may be ZMQ::DONTWAIT.
330
328
  #
331
329
  # Returns 0 when the message was successfully dequeued.
332
330
  # Returns -1 under two conditions.
333
331
  # 1. The message could not be dequeued
334
- # 2. When +flags+ is set with ZMQ::NonBlocking and the socket returned EAGAIN.
332
+ # 2. When +flags+ is set with ZMQ::DONTWAIT and the socket returned EAGAIN.
335
333
  #
336
- # With a -1 return code, the user must check ZMQ.errno to determine the
334
+ # With a -1 return code, the user must check ZMQ::Util.errno to determine the
337
335
  # cause.
338
336
  #
339
337
  # The application code is responsible for handling the +message+ object lifecycle
@@ -349,7 +347,7 @@ module ZMQ
349
347
 
350
348
  # Receive a multipart message as a list of strings.
351
349
  #
352
- # +flag+ may be ZMQ::NonBlocking. Any other flag will be
350
+ # +flag+ may be ZMQ::DONTWAIT. Any other flag will be
353
351
  # removed.
354
352
  #
355
353
  def recv_strings list, flag = 0
@@ -369,11 +367,11 @@ module ZMQ
369
367
  # Receive a multipart message as an array of objects
370
368
  # (by default these are instances of Message).
371
369
  #
372
- # +flag+ may be ZMQ::NonBlocking. Any other flag will be
370
+ # +flag+ may be ZMQ::DONTWAIT. Any other flag will be
373
371
  # removed.
374
372
  #
375
373
  def recvmsgs list, flag = 0
376
- flag = NonBlocking if dontwait?(flag)
374
+ flag = DONTWAIT if dontwait?(flag)
377
375
 
378
376
  message = @receiver_klass.new
379
377
  rc = recvmsg message, flag
@@ -426,24 +424,96 @@ module ZMQ
426
424
  rc
427
425
  end
428
426
 
427
+ # Get the options set on this socket.
428
+ #
429
+ # +name+ determines the socket option to request
430
+ # +array+ should be an empty array; a result of the proper type
431
+ # (numeric, string, boolean) will be inserted into
432
+ # the first position.
433
+ #
434
+ # Valid +option_name+ values:
435
+ # ZMQ::RCVMORE - true or false
436
+ # ZMQ::HWM - integer
437
+ # ZMQ::SWAP - integer
438
+ # ZMQ::AFFINITY - bitmap in an integer
439
+ # ZMQ::IDENTITY - string
440
+ # ZMQ::RATE - integer
441
+ # ZMQ::RECOVERY_IVL - integer
442
+ # ZMQ::SNDBUF - integer
443
+ # ZMQ::RCVBUF - integer
444
+ # ZMQ::FD - fd in an integer
445
+ # ZMQ::EVENTS - bitmap integer
446
+ # ZMQ::LINGER - integer measured in milliseconds
447
+ # ZMQ::RECONNECT_IVL - integer measured in milliseconds
448
+ # ZMQ::BACKLOG - integer
449
+ # ZMQ::RECOVER_IVL_MSEC - integer measured in milliseconds
450
+ # ZMQ::IPV4ONLY - integer
451
+ #
452
+ # Returns 0 when the operation completed successfully.
453
+ # Returns -1 when this operation failed.
454
+ #
455
+ # With a -1 return code, the user must check ZMQ::Util.errno to determine the
456
+ # cause.
457
+ #
458
+ # # retrieve high water mark
459
+ # array = []
460
+ # rc = socket.getsockopt(ZMQ::HWM, array)
461
+ # hwm = array.first if ZMQ::Util.resultcode_ok?(rc)
462
+ #
463
+ def getsockopt name, array
464
+ rc = __getsockopt__ name, array
465
+
466
+ if Util.resultcode_ok?(rc) && (RCVMORE == name)
467
+ # convert to boolean
468
+ array[0] = 1 == array[0]
469
+ end
470
+
471
+ rc
472
+ end
473
+
474
+ # Convenience method for getting the value of the socket IDENTITY.
475
+ #
476
+ def identity
477
+ array = []
478
+ getsockopt IDENTITY, array
479
+ array.at(0)
480
+ end
481
+
482
+ # Convenience method for setting the value of the socket IDENTITY.
483
+ #
484
+ def identity=(value)
485
+ setsockopt IDENTITY, value.to_s
486
+ end
487
+
488
+ # Disconnect the socket from the given +endpoint+.
489
+ #
490
+ def disconnect(endpoint)
491
+ LibZMQ.zmq_disconnect(socket, endpoint)
492
+ end
493
+
494
+ # Unbind the socket from the given +endpoint+.
495
+ #
496
+ def unbind(endpoint)
497
+ LibZMQ.zmq_unbind(socket, endpoint)
498
+ end
499
+
429
500
 
430
501
  private
431
-
502
+
432
503
  def send_multiple(parts, flags, method_name)
433
504
  if !parts || parts.empty?
434
505
  -1
435
506
  else
436
- flags = NonBlocking if dontwait?(flags)
507
+ flags = DONTWAIT if dontwait?(flags)
437
508
  rc = 0
438
-
509
+
439
510
  parts[0..-2].each do |part|
440
511
  rc = send(method_name, part, (flags | ZMQ::SNDMORE))
441
512
  break unless Util.resultcode_ok?(rc)
442
513
  end
443
-
514
+
444
515
  Util.resultcode_ok?(rc) ? send(method_name, parts[-1], flags) : rc
445
516
  end
446
-
447
517
  end
448
518
 
449
519
  def __getsockopt__ name, array
@@ -485,277 +555,57 @@ module ZMQ
485
555
  alloc_pointer(255, 255)
486
556
 
487
557
  else
488
- # uh oh, someone passed in an unknown option; use a slop buffer
558
+ # uh oh, someone passed in an unknown option; return nil
489
559
  @int_cache ||= alloc_pointer(:int32, 4)
490
560
  end
491
561
  end
492
562
 
493
- def populate_option_lookup
494
- # integer options
495
- [EVENTS, LINGER, RCVTIMEO, SNDTIMEO, RECONNECT_IVL, FD, TYPE, BACKLOG].each { |option| @option_lookup[option] = 0 }
496
-
497
- # long long options
498
- [RCVMORE, AFFINITY].each { |option| @option_lookup[option] = 1 }
499
-
500
- # string options
501
- [SUBSCRIBE, UNSUBSCRIBE].each { |option| @option_lookup[option] = 2 }
502
- end
503
-
504
563
  def release_cache
505
564
  @longlong_cache = nil
506
565
  @int_cache = nil
507
566
  end
508
567
 
509
568
  def dontwait?(flags)
510
- (NonBlocking & flags) == NonBlocking
569
+ (DONTWAIT & flags) == DONTWAIT
511
570
  end
512
571
  alias :noblock? :dontwait?
513
-
572
+
514
573
  def alloc_pointer(kind, length)
515
574
  pointer = FFI::MemoryPointer.new :size_t
516
575
  pointer.write_int(length)
517
576
  [FFI::MemoryPointer.new(kind), pointer]
518
577
  end
519
- end # module CommonSocketBehavior
520
578
 
521
-
522
- module IdentitySupport
523
-
524
- # Convenience method for getting the value of the socket IDENTITY.
525
- #
526
- def identity
527
- array = []
528
- getsockopt IDENTITY, array
529
- array.at(0)
579
+ def __sendmsg__(socket, address, flags)
580
+ LibZMQ.zmq_sendmsg(socket, address, flags)
530
581
  end
531
582
 
532
- # Convenience method for setting the value of the socket IDENTITY.
533
- #
534
- def identity=(value)
535
- setsockopt IDENTITY, value.to_s
583
+ def __recvmsg__(socket, address, flags)
584
+ LibZMQ.zmq_recvmsg(socket, address, flags)
536
585
  end
537
586
 
538
-
539
- private
540
-
541
587
  def populate_option_lookup
542
- super()
543
-
544
- # string options
545
- [IDENTITY].each { |option| @option_lookup[option] = 2 }
546
- end
547
-
548
- end # module IdentitySupport
549
-
550
-
551
- if LibZMQ.version2?
552
-
553
- class Socket
554
- # Inclusion order is *important* since later modules may have a call
555
- # to #super. We want those calls to go up the chain in a particular
556
- # order
557
- include CommonSocketBehavior
558
- include IdentitySupport
559
-
560
- # Get the options set on this socket.
561
- #
562
- # +name+ determines the socket option to request
563
- # +array+ should be an empty array; a result of the proper type
564
- # (numeric, string, boolean) will be inserted into
565
- # the first position.
566
- #
567
- # Valid +option_name+ values:
568
- # ZMQ::RCVMORE - true or false
569
- # ZMQ::HWM - integer
570
- # ZMQ::SWAP - integer
571
- # ZMQ::AFFINITY - bitmap in an integer
572
- # ZMQ::IDENTITY - string
573
- # ZMQ::RATE - integer
574
- # ZMQ::RECOVERY_IVL - integer
575
- # ZMQ::MCAST_LOOP - true or false
576
- # ZMQ::SNDBUF - integer
577
- # ZMQ::RCVBUF - integer
578
- # ZMQ::FD - fd in an integer
579
- # ZMQ::EVENTS - bitmap integer
580
- # ZMQ::LINGER - integer measured in milliseconds
581
- # ZMQ::RECONNECT_IVL - integer measured in milliseconds
582
- # ZMQ::BACKLOG - integer
583
- # ZMQ::RECOVER_IVL_MSEC - integer measured in milliseconds
584
- #
585
- # Returns 0 when the operation completed successfully.
586
- # Returns -1 when this operation failed.
587
- #
588
- # With a -1 return code, the user must check ZMQ.errno to determine the
589
- # cause.
590
- #
591
- # # retrieve high water mark
592
- # array = []
593
- # rc = socket.getsockopt(ZMQ::HWM, array)
594
- # hwm = array.first if ZMQ::Util.resultcode_ok?(rc)
595
- #
596
- def getsockopt name, array
597
- rc = __getsockopt__ name, array
598
-
599
- if Util.resultcode_ok?(rc) && (RCVMORE == name || MCAST_LOOP == name)
600
- # convert to boolean
601
- array[0] = 1 == array[0]
602
- end
603
-
604
- rc
605
- end
606
-
588
+ IntegerSocketOptions.each { |option| @option_lookup[option] = 0 }
607
589
 
608
- private
609
-
610
- def __sendmsg__(socket, address, flags)
611
- LibZMQ.zmq_send(socket, address, flags)
612
- end
613
-
614
- def __recvmsg__(socket, address, flags)
615
- LibZMQ.zmq_recv(socket, address, flags)
616
- end
617
-
618
- def populate_option_lookup
619
- super()
620
-
621
- # integer options
622
- [RECONNECT_IVL_MAX].each { |option| @option_lookup[option] = 0 }
623
-
624
- # long long options
625
- [HWM, SWAP, RATE, RECOVERY_IVL, RECOVERY_IVL_MSEC, MCAST_LOOP, SNDBUF, RCVBUF].each { |option| @option_lookup[option] = 1 }
626
- end
627
-
628
- # these finalizer-related methods cannot live in the CommonSocketBehavior
629
- # module; they *must* be in the class definition directly
630
-
631
- def define_finalizer
632
- ObjectSpace.define_finalizer(self, self.class.close(@socket, Process.pid))
633
- end
634
-
635
- def remove_finalizer
636
- ObjectSpace.undefine_finalizer self
637
- end
590
+ LongLongSocketOptions.each { |option| @option_lookup[option] = 1 }
638
591
 
639
- def self.close socket, pid
640
- Proc.new do
641
- LibZMQ.zmq_close(socket) if socket && !socket.nil? && Process.pid == pid
642
- end
643
- end
644
- end # class Socket for version2
645
-
646
- end # LibZMQ.version2?
647
-
648
-
649
- if LibZMQ.version3?
650
- class Socket
651
- include CommonSocketBehavior
652
- include IdentitySupport
653
-
654
- # Get the options set on this socket.
655
- #
656
- # +name+ determines the socket option to request
657
- # +array+ should be an empty array; a result of the proper type
658
- # (numeric, string, boolean) will be inserted into
659
- # the first position.
660
- #
661
- # Valid +option_name+ values:
662
- # ZMQ::RCVMORE - true or false
663
- # ZMQ::HWM - integer
664
- # ZMQ::SWAP - integer
665
- # ZMQ::AFFINITY - bitmap in an integer
666
- # ZMQ::IDENTITY - string
667
- # ZMQ::RATE - integer
668
- # ZMQ::RECOVERY_IVL - integer
669
- # ZMQ::SNDBUF - integer
670
- # ZMQ::RCVBUF - integer
671
- # ZMQ::FD - fd in an integer
672
- # ZMQ::EVENTS - bitmap integer
673
- # ZMQ::LINGER - integer measured in milliseconds
674
- # ZMQ::RECONNECT_IVL - integer measured in milliseconds
675
- # ZMQ::BACKLOG - integer
676
- # ZMQ::RECOVER_IVL_MSEC - integer measured in milliseconds
677
- # ZMQ::IPV4ONLY - integer
678
- #
679
- # Returns 0 when the operation completed successfully.
680
- # Returns -1 when this operation failed.
681
- #
682
- # With a -1 return code, the user must check ZMQ.errno to determine the
683
- # cause.
684
- #
685
- # # retrieve high water mark
686
- # array = []
687
- # rc = socket.getsockopt(ZMQ::HWM, array)
688
- # hwm = array.first if ZMQ::Util.resultcode_ok?(rc)
689
- #
690
- def getsockopt name, array
691
- rc = __getsockopt__ name, array
692
-
693
- if Util.resultcode_ok?(rc) && (RCVMORE == name)
694
- # convert to boolean
695
- array[0] = 1 == array[0]
696
- end
697
-
698
- rc
699
- end
700
-
701
- # Version3 only
702
- #
703
- # Disconnect the socket from the given +endpoint+.
704
- #
705
- def disconnect(endpoint)
706
- LibZMQ.zmq_disconnect(socket, endpoint)
707
- end
708
-
709
- # Version3 only
710
- #
711
- # Unbind the socket from the given +endpoint+.
712
- #
713
- def unbind(endpoint)
714
- LibZMQ.zmq_unbind(socket, endpoint)
715
- end
716
-
717
-
718
- private
719
-
720
- def __sendmsg__(socket, address, flags)
721
- LibZMQ.zmq_sendmsg(socket, address, flags)
722
- end
723
-
724
- def __recvmsg__(socket, address, flags)
725
- LibZMQ.zmq_recvmsg(socket, address, flags)
726
- end
727
-
728
- def populate_option_lookup
729
- super()
730
-
731
- # integer options
732
- [RECONNECT_IVL_MAX, RCVHWM, SNDHWM, RATE, RECOVERY_IVL, SNDBUF, RCVBUF, IPV4ONLY,
733
- ROUTER_BEHAVIOR, TCP_KEEPALIVE, TCP_KEEPALIVE_CNT,
734
- TCP_KEEPALIVE_IDLE, TCP_KEEPALIVE_INTVL, TCP_ACCEPT_FILTER, MULTICAST_HOPS
735
- ].each { |option| @option_lookup[option] = 0 }
736
-
737
- # long long options
738
- [MAXMSGSIZE].each { |option| @option_lookup[option] = 1 }
739
-
740
- # string options
741
- [LAST_ENDPOINT].each { |option| @option_lookup[option] = 2 }
742
- end
592
+ StringSocketOptions.each { |option| @option_lookup[option] = 2 }
593
+ end
743
594
 
744
- # these finalizer-related methods cannot live in the CommonSocketBehavior
745
- # module; they *must* be in the class definition directly
595
+ # these finalizer-related methods cannot live in the CommonSocketBehavior
596
+ # module; they *must* be in the class definition directly
746
597
 
747
- def define_finalizer
748
- ObjectSpace.define_finalizer(self, self.class.close(@socket, Process.pid))
749
- end
598
+ def define_finalizer
599
+ ObjectSpace.define_finalizer(self, self.class.close(@socket, Process.pid))
600
+ end
750
601
 
751
- def remove_finalizer
752
- ObjectSpace.undefine_finalizer self
753
- end
602
+ def remove_finalizer
603
+ ObjectSpace.undefine_finalizer self
604
+ end
754
605
 
755
- def self.close socket, pid
756
- Proc.new { LibZMQ.zmq_close socket if Process.pid == pid }
757
- end
758
- end # Socket for version3
759
- end # LibZMQ.version3?
606
+ def self.close socket, pid
607
+ Proc.new { LibZMQ.zmq_close socket if Process.pid == pid }
608
+ end
609
+ end # Socket
760
610
 
761
611
  end # module ZMQ