cztop 1.0.0 → 1.1.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/coverage.yml +20 -0
  3. data/.github/workflows/draft_api.yml +27 -0
  4. data/.github/workflows/{main.yml → stable_api.yml} +6 -6
  5. data/.rubocop.yml +175 -0
  6. data/CHANGES.md +8 -1
  7. data/Gemfile +5 -0
  8. data/README.md +3 -1
  9. data/ci/install-libczmq +22 -0
  10. data/ci/install-libzmq +22 -0
  11. data/cztop.gemspec +3 -2
  12. data/lib/cztop/actor.rb +55 -26
  13. data/lib/cztop/authenticator.rb +18 -9
  14. data/lib/cztop/beacon.rb +22 -10
  15. data/lib/cztop/cert_store.rb +8 -2
  16. data/lib/cztop/certificate.rb +47 -18
  17. data/lib/cztop/config/comments.rb +14 -3
  18. data/lib/cztop/config/serialization.rb +25 -5
  19. data/lib/cztop/config/traversing.rb +44 -13
  20. data/lib/cztop/config.rb +23 -9
  21. data/lib/cztop/frame.rb +23 -10
  22. data/lib/cztop/has_ffi_delegate.rb +11 -1
  23. data/lib/cztop/message/frames.rb +16 -2
  24. data/lib/cztop/message.rb +36 -22
  25. data/lib/cztop/metadata.rb +35 -24
  26. data/lib/cztop/monitor.rb +14 -5
  27. data/lib/cztop/poller/aggregated.rb +31 -15
  28. data/lib/cztop/poller/zmq.rb +25 -22
  29. data/lib/cztop/poller/zpoller.rb +18 -6
  30. data/lib/cztop/poller.rb +43 -18
  31. data/lib/cztop/polymorphic_zsock_methods.rb +6 -1
  32. data/lib/cztop/proxy.rb +34 -19
  33. data/lib/cztop/send_receive_methods.rb +5 -1
  34. data/lib/cztop/socket/types.rb +128 -22
  35. data/lib/cztop/socket.rb +23 -18
  36. data/lib/cztop/version.rb +5 -1
  37. data/lib/cztop/z85/padded.rb +12 -3
  38. data/lib/cztop/z85/pipe.rb +40 -17
  39. data/lib/cztop/z85.rb +17 -6
  40. data/lib/cztop/zap.rb +57 -32
  41. data/lib/cztop/zsock_options.rb +155 -122
  42. data/lib/cztop.rb +2 -1
  43. metadata +28 -10
  44. data/.ruby-version +0 -1
data/lib/cztop/message.rb CHANGED
@@ -1,6 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CZTop
2
4
  # Represents a CZMQ::FFI::Zmsg.
3
5
  class Message
6
+
4
7
  include HasFFIDelegate
5
8
  extend CZTop::HasFFIDelegate::ClassMethods
6
9
  include ::CZMQ::FFI
@@ -12,14 +15,15 @@ module CZTop
12
15
  def self.coerce(msg)
13
16
  case msg
14
17
  when Message
15
- return msg
18
+ msg
16
19
  when String, Frame, Array
17
- return new(msg)
20
+ new(msg)
18
21
  else
19
- raise ArgumentError, "cannot coerce message: %p" % msg
22
+ raise ArgumentError, format('cannot coerce message: %p', msg)
20
23
  end
21
24
  end
22
25
 
26
+
23
27
  # @param parts [String, Frame, Array<String>, Array<Frame>] initial parts
24
28
  # of the message
25
29
  def initialize(parts = nil)
@@ -27,11 +31,13 @@ module CZTop
27
31
  Array(parts).each { |part| self << part } if parts
28
32
  end
29
33
 
34
+
30
35
  # @return [Boolean] if this message is empty or not
31
36
  def empty?
32
37
  content_size.zero?
33
38
  end
34
39
 
40
+
35
41
  # Send {Message} to a {Socket} or {Actor}.
36
42
  #
37
43
  # @note Do NOT use this {Message} anymore afterwards. Its native
@@ -56,12 +62,14 @@ module CZTop
56
62
  #
57
63
  def send_to(destination)
58
64
  rc = Zmsg.send(ffi_delegate, destination)
59
- return if rc == 0
65
+ return if rc.zero?
66
+
60
67
  raise_zmq_err
61
68
  rescue Errno::EAGAIN
62
69
  raise IO::EAGAINWaitWritable
63
70
  end
64
71
 
72
+
65
73
  # Receive a {Message} from a {Socket} or {Actor}.
66
74
  # @param source [Socket, Actor]
67
75
  # @return [Message] the newly received message
@@ -73,11 +81,13 @@ module CZTop
73
81
  def self.receive_from(source)
74
82
  delegate = Zmsg.recv(source)
75
83
  return from_ffi_delegate(delegate) unless delegate.null?
84
+
76
85
  HasFFIDelegate.raise_zmq_err
77
86
  rescue Errno::EAGAIN
78
87
  raise IO::EAGAINWaitReadable
79
88
  end
80
89
 
90
+
81
91
  # Append a frame to this message.
82
92
  # @param frame [String, Frame] what to append
83
93
  # @raise [ArgumentError] if frame has an invalid type
@@ -90,16 +100,17 @@ module CZTop
90
100
  when String
91
101
  # NOTE: can't use addstr because the data might be binary
92
102
  mem = FFI::MemoryPointer.from_string(frame)
93
- rc = ffi_delegate.addmem(mem, mem.size - 1) # without NULL byte
103
+ rc = ffi_delegate.addmem(mem, mem.size - 1) # without NULL byte
94
104
  when Frame
95
105
  rc = ffi_delegate.append(frame.ffi_delegate)
96
106
  else
97
- raise ArgumentError, "invalid frame: %p" % frame
107
+ raise ArgumentError, format('invalid frame: %p', frame)
98
108
  end
99
- raise_zmq_err unless rc == 0
109
+ raise_zmq_err unless rc.zero?
100
110
  self
101
111
  end
102
112
 
113
+
103
114
  # Prepend a frame to this message.
104
115
  # @param frame [String, Frame] what to prepend
105
116
  # @raise [ArgumentError] if frame has an invalid type
@@ -112,30 +123,34 @@ module CZTop
112
123
  when String
113
124
  # NOTE: can't use pushstr because the data might be binary
114
125
  mem = FFI::MemoryPointer.from_string(frame)
115
- rc = ffi_delegate.pushmem(mem, mem.size - 1) # without NULL byte
126
+ rc = ffi_delegate.pushmem(mem, mem.size - 1) # without NULL byte
116
127
  when Frame
117
128
  rc = ffi_delegate.prepend(frame.ffi_delegate)
118
129
  else
119
- raise ArgumentError, "invalid frame: %p" % frame
130
+ raise ArgumentError, format('invalid frame: %p', frame)
120
131
  end
121
- raise_zmq_err unless rc == 0
132
+ raise_zmq_err unless rc.zero?
122
133
  end
123
134
 
135
+
124
136
  # Removes first part from message and returns it as a string.
125
137
  # @return [String, nil] first part, if any, or nil
126
138
  def pop
127
139
  # NOTE: can't use popstr because the data might be binary
128
140
  ptr = ffi_delegate.pop
129
141
  return nil if ptr.null?
142
+
130
143
  Frame.from_ffi_delegate(ptr).to_s
131
144
  end
132
145
 
146
+
133
147
  # @return [Integer] size of this message in bytes
134
148
  # @see size
135
149
  def content_size
136
150
  ffi_delegate.content_size
137
151
  end
138
152
 
153
+
139
154
  # Returns all frames as strings in an array. This is useful if for quick
140
155
  # inspection of the message.
141
156
  # @note It'll read all frames in the message and turn them into Ruby
@@ -143,30 +158,27 @@ module CZTop
143
158
  # @return [Array<String>] all frames
144
159
  def to_a
145
160
  ffi_delegate = ffi_delegate()
146
- frame = ffi_delegate.first
161
+ frame = ffi_delegate.first
147
162
  return [] if frame.null?
148
163
 
149
- arr = [ frame.data.read_bytes(frame.size) ]
150
- while frame = ffi_delegate.next and not frame.null?
164
+ arr = [frame.data.read_bytes(frame.size)]
165
+ while (frame = ffi_delegate.next) && !frame.null?
151
166
  arr << frame.data.read_bytes(frame.size)
152
167
  end
153
168
 
154
- return arr
169
+ arr
155
170
  end
156
171
 
172
+
157
173
  # Inspects this {Message}.
158
174
  # @return [String] shows class, number of frames, content size, and
159
175
  # content (only if it's up to 200 bytes)
160
176
  def inspect
161
- "#<%s:0x%x frames=%i content_size=%i content=%s>" % [
162
- self.class,
163
- to_ptr.address,
164
- size,
165
- content_size,
166
- content_size <= 500 ? to_a.inspect : "[...]"
167
- ]
177
+ format('#<%s:0x%x frames=%i content_size=%i content=%s>', self.class, to_ptr.address, size, content_size,
178
+ content_size <= 500 ? to_a.inspect : '[...]')
168
179
  end
169
180
 
181
+
170
182
  # Return a frame's content.
171
183
  # @return [String] the frame's content, if it exists
172
184
  # @return [nil] if frame doesn't exist at given index
@@ -193,8 +205,10 @@ module CZTop
193
205
 
194
206
  # need to raise manually, as FFI lacks this feature.
195
207
  # @see https://github.com/ffi/ffi/issues/473
196
- raise RangeError if new_routing_id < 0
208
+ raise RangeError if new_routing_id.negative?
209
+
197
210
  ffi_delegate.set_routing_id(new_routing_id)
198
211
  end
212
+
199
213
  end
200
214
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'set'
2
4
 
3
5
  module CZTop
@@ -13,12 +15,15 @@ module CZTop
13
15
  #
14
16
  # @see https://rfc.zeromq.org/spec:23/ZMTP
15
17
  class Metadata
16
- VALUE_MAXLEN = 2**31-1
18
+
19
+ VALUE_MAXLEN = (2**31) - 1
20
+
17
21
 
18
22
  # Raised when decoding malformed metadata.
19
23
  class InvalidData < StandardError
20
24
  end
21
25
 
26
+
22
27
  # regular expression used to validate property names
23
28
  NAME_REGEX = /\A[[:alnum:]_.+-]{1,255}\Z/.freeze
24
29
 
@@ -29,47 +34,49 @@ module CZTop
29
34
  # @return [String]
30
35
  def self.dump(metadata)
31
36
  ic_names = Set.new
37
+
32
38
  metadata.map do |k, v|
33
39
  ic_name = k.to_sym.downcase
34
- if ic_names.include?(ic_name)
35
- raise ArgumentError, "property #{k.inspect}: duplicate name"
36
- else
37
- ic_names << ic_name
38
- end
40
+ raise ArgumentError, "property #{k.inspect}: duplicate name" if ic_names.include? ic_name
41
+
42
+ ic_names << ic_name
43
+
39
44
  name = k.to_s
40
- if NAME_REGEX !~ name
41
- raise ArgumentError, "property #{k.inspect}: invalid name"
42
- end
45
+ raise ArgumentError, "property #{k.inspect}: invalid name" if NAME_REGEX !~ name
46
+
43
47
  value = v.to_s
44
- if value.bytesize > VALUE_MAXLEN
45
- raise ArgumentError, "property #{k.inspect}: value too long"
46
- end
47
- [name.size, name, value.bytesize, value].pack("CA*NA*")
48
+ raise ArgumentError, "property #{k.inspect}: value too long" if value.bytesize > VALUE_MAXLEN
49
+
50
+ [name.size, name, value.bytesize, value].pack('CA*NA*')
48
51
  end.join
49
52
  end
50
53
 
54
+
51
55
  # @param data [String, Frame, #to_s] the data representing the metadata
52
56
  # @return [Hash]
53
57
  def self.load(data)
54
58
  properties = {}
55
- consumed = 0
59
+ consumed = 0
60
+
56
61
  while consumed < data.bytesize # while there are bytes to read
57
62
  # read property name
58
- name_length = data.byteslice(consumed).unpack("C").first # never nil
59
- raise InvalidData, "zero-length property name" if name_length.zero?
63
+ name_length = data.byteslice(consumed).unpack1('C') # never nil
64
+ raise InvalidData, 'zero-length property name' if name_length.zero?
65
+
60
66
  name = data.byteslice(consumed + 1, name_length)
61
- raise InvalidData, "incomplete name" if name.bytesize != name_length
67
+ raise InvalidData, 'incomplete name' if name.bytesize != name_length
68
+
62
69
  name_sym = name.to_sym.downcase
63
- if properties.has_key?(name_sym)
64
- raise InvalidData, "property #{name.inspect}: duplicate name"
65
- end
70
+ raise InvalidData, "property #{name.inspect}: duplicate name" if properties.key?(name_sym)
71
+
66
72
  consumed += 1 + name.bytesize
67
73
 
68
74
  # read property value
69
- value_length = data.byteslice(consumed, 4).unpack("N").first or
70
- raise InvalidData, "incomplete length"
71
- value = data.byteslice(consumed + 4, value_length)
72
- raise InvalidData, "incomplete value" if value.bytesize != value_length
75
+ value_length = data.byteslice(consumed, 4).unpack1('N') or
76
+ raise InvalidData, 'incomplete length'
77
+ value = data.byteslice(consumed + 4, value_length)
78
+ raise InvalidData, 'incomplete value' if value.bytesize != value_length
79
+
73
80
  consumed += 4 + value.bytesize
74
81
 
75
82
  # remember
@@ -78,12 +85,14 @@ module CZTop
78
85
  new(properties)
79
86
  end
80
87
 
88
+
81
89
  # @param properties [Hash<Symbol, String>] the properties as loaded by
82
90
  # {load}
83
91
  def initialize(properties)
84
92
  @properties = properties
85
93
  end
86
94
 
95
+
87
96
  # Gets the value corresponding to a property name. The case of the name
88
97
  # is insignificant.
89
98
  # @param name [Symbol, String] the property name
@@ -92,9 +101,11 @@ module CZTop
92
101
  @properties[name.to_sym.downcase]
93
102
  end
94
103
 
104
+
95
105
  # @return [Hash<Symbol, String] all properties
96
106
  def to_h
97
107
  @properties
98
108
  end
109
+
99
110
  end
100
111
  end
data/lib/cztop/monitor.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CZTop
2
4
  # CZMQ monitor. Listen for socket events.
3
5
  #
@@ -8,11 +10,12 @@ module CZTop
8
10
  # @see http://api.zeromq.org/czmq3-0:zmonitor
9
11
  # @see http://api.zeromq.org/4-1:zmq-socket-monitor
10
12
  class Monitor
13
+
11
14
  include ::CZMQ::FFI
12
15
 
13
16
  # function pointer to the +zmonitor()+ function
14
17
  ZMONITOR_FPTR = ::CZMQ::FFI.ffi_libraries.each do |dl|
15
- fptr = dl.find_function("zmonitor")
18
+ fptr = dl.find_function('zmonitor')
16
19
  break fptr if fptr
17
20
  end
18
21
  raise LoadError, "couldn't find zmonitor()" if ZMONITOR_FPTR.nil?
@@ -31,10 +34,11 @@ module CZTop
31
34
  @actor.terminate
32
35
  end
33
36
 
37
+
34
38
  # Enable verbose logging of commands and activity.
35
39
  # @return [void]
36
40
  def verbose!
37
- @actor << "VERBOSE"
41
+ @actor << 'VERBOSE'
38
42
  end
39
43
 
40
44
  # @return [Array<String>] types of valid events
@@ -55,7 +59,7 @@ module CZTop
55
59
  HANDSHAKE_FAILED_NO_DETAIL
56
60
  HANDSHAKE_FAILED_PROTOCOL
57
61
  HANDSHAKE_FAILED_AUTH
58
- ]
62
+ ].freeze
59
63
 
60
64
  # Configure monitor to listen for specific events.
61
65
  # @param events [String] one or more events from {EVENTS}
@@ -65,16 +69,18 @@ module CZTop
65
69
  EVENTS.include?(event) or
66
70
  raise ArgumentError, "invalid event: #{event.inspect}"
67
71
  end
68
- @actor << [ "LISTEN", *events ]
72
+ @actor << ['LISTEN', *events]
69
73
  end
70
74
 
75
+
71
76
  # Start the monitor. After this, you can read events using {#next}.
72
77
  # @return [void]
73
78
  def start
74
- @actor << "START"
79
+ @actor << 'START'
75
80
  @actor.wait
76
81
  end
77
82
 
83
+
78
84
  # Useful for registration in an event-loop.
79
85
  # @return [Integer] the FD
80
86
  # @see ZsockOptions#fd
@@ -82,11 +88,13 @@ module CZTop
82
88
  @actor.fd
83
89
  end
84
90
 
91
+
85
92
  # @return [Boolean] whether there's at least one event available
86
93
  def readable?
87
94
  @actor.readable?
88
95
  end
89
96
 
97
+
90
98
  # Get next event. This blocks until the next event is available.
91
99
  # @example
92
100
  # socket = CZTop::Socket::ROUTER.new("tcp://127.0.0.1:5050")
@@ -112,5 +120,6 @@ module CZTop
112
120
  def next
113
121
  @actor.receive
114
122
  end
123
+
115
124
  end
116
125
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CZTop
2
4
  # This is a poller which is able to provide a list of readable and a list
3
5
  # of writable sockets. This is useful for when you need to process socket
@@ -37,31 +39,37 @@ module CZTop
37
39
  # @return [CZTop::Poller.new] the associated (regular) poller
38
40
  attr_reader :poller
39
41
 
42
+
40
43
  # @return [Array<CZTop::Socket>] readable sockets
41
44
  attr_reader :readables
42
45
 
46
+
43
47
  # @return [Array<CZTop::Socket>] writable sockets
44
48
  attr_reader :writables
45
49
 
50
+
46
51
  extend Forwardable
52
+
47
53
  def_delegators :@poller,
48
- :add,
49
- :add_reader,
50
- :add_writer,
51
- :modify,
52
- :remove,
53
- :remove_reader,
54
- :remove_writer,
55
- :sockets
54
+ :add,
55
+ :add_reader,
56
+ :add_writer,
57
+ :modify,
58
+ :remove,
59
+ :remove_reader,
60
+ :remove_writer,
61
+ :sockets
62
+
56
63
 
57
64
  # Initializes the aggregated poller.
58
65
  # @param poller [CZTop::Poller] the wrapped poller
59
66
  def initialize(poller = CZTop::Poller.new)
60
67
  @readables = []
61
68
  @writables = []
62
- @poller = poller
69
+ @poller = poller
63
70
  end
64
71
 
72
+
65
73
  # Forgets all previous event information (which sockets are
66
74
  # readable/writable) and waits for events anew. After getting the first
67
75
  # event, {CZTop::Poller#wait} is called again with a zero-timeout to get
@@ -76,26 +84,29 @@ module CZTop
76
84
  # or -1 to wait indefinitely
77
85
  # @return [Boolean] whether there have been any events
78
86
  def wait(timeout = -1)
79
- @readables = []
80
- @writables = []
87
+ @readables = []
88
+ @writables = []
81
89
  @event_masks = {}
82
90
 
83
- if event = @poller.wait(timeout)
91
+ if (event = @poller.wait(timeout))
84
92
  extract(event)
85
93
 
86
94
  # get all other pending events, if any, but no more blocking
87
- while event = @poller.wait(0)
95
+ while (event = @poller.wait 0)
88
96
  extract(event)
89
97
  end
90
98
 
91
99
  restore_event_masks
92
100
  return true
93
101
  end
94
- return false
102
+
103
+ false
95
104
  end
96
105
 
106
+
97
107
  private
98
108
 
109
+
99
110
  # Extracts the event information, adds the socket to the correct list(s)
100
111
  # and modifies the socket's event mask for the socket to not turn up
101
112
  # again during the next call(s) to {CZTop::Poller#wait} within {#wait}.
@@ -103,24 +114,29 @@ module CZTop
103
114
  # @param event [CZTop::Poller::Event]
104
115
  # @return [void]
105
116
  def extract(event)
106
- event_mask = poller.event_mask_for_socket(event.socket)
117
+ event_mask = poller.event_mask_for_socket(event.socket)
107
118
  @event_masks[event.socket] = event_mask
119
+
108
120
  if event.readable?
109
121
  @readables << event.socket
110
122
  event_mask &= 0xFFFF ^ CZTop::Poller::ZMQ::POLLIN
111
123
  end
124
+
112
125
  if event.writable?
113
126
  @writables << event.socket
114
127
  event_mask &= 0xFFFF ^ CZTop::Poller::ZMQ::POLLOUT
115
128
  end
129
+
116
130
  poller.modify(event.socket, event_mask)
117
131
  end
118
132
 
133
+
119
134
  # Restores the event mask for all registered sockets to the state they
120
135
  # were before the call to {#wait}.
121
136
  # @return [void]
122
137
  def restore_event_masks
123
138
  @event_masks.each { |socket, mask| poller.modify(socket, mask) }
124
139
  end
140
+
125
141
  end
126
142
  end
@@ -1,5 +1,6 @@
1
- module CZTop
1
+ # frozen_string_literal: true
2
2
 
3
+ module CZTop
3
4
  # CZTop's interface to the low-level +zmq_poller_*()+ functions.
4
5
  module Poller::ZMQ
5
6
 
@@ -8,9 +9,9 @@ module CZTop
8
9
  POLLERR = 4
9
10
 
10
11
  extend ::FFI::Library
11
- lib_name = 'libzmq'
12
- lib_dirs = ['/usr/local/lib', '/opt/local/lib', '/usr/lib64']
13
- lib_dirs = [*ENV['LIBZMQ_PATH'].split(':'), *lib_dirs] if ENV['LIBZMQ_PATH']
12
+ lib_name = 'libzmq'
13
+ lib_dirs = ['/usr/local/lib', '/opt/local/lib', '/usr/lib64']
14
+ lib_dirs = [*ENV['LIBZMQ_PATH'].split(':'), *lib_dirs] if ENV['LIBZMQ_PATH']
14
15
  lib_paths = lib_dirs.map { |path| "#{path}/#{lib_name}.#{::FFI::Platform::LIBSUFFIX}" }
15
16
  ffi_lib lib_paths + [lib_name]
16
17
 
@@ -24,6 +25,7 @@ module CZTop
24
25
  # short events;
25
26
  # } zmq_poller_event_t;
26
27
  class PollerEvent < FFI::Struct
28
+
27
29
  layout :socket, :pointer,
28
30
  :fd, :int,
29
31
  :user_data, :pointer,
@@ -31,21 +33,23 @@ module CZTop
31
33
 
32
34
  # @return [Boolean] whether the socket is readable
33
35
  def readable?
34
- (self[:events] & POLLIN) > 0
36
+ (self[:events] & POLLIN).positive?
35
37
  end
36
38
 
39
+
37
40
  # @return [Boolean] whether the socket is writable
38
41
  def writable?
39
- (self[:events] & POLLOUT) > 0
42
+ (self[:events] & POLLOUT).positive?
40
43
  end
44
+
41
45
  end
42
46
 
43
- #ZMQ_EXPORT void *zmq_poller_new (void);
44
- #ZMQ_EXPORT int zmq_poller_destroy (void **poller_p);
45
- #ZMQ_EXPORT int zmq_poller_add (void *poller, void *socket, void *user_data, short events);
46
- #ZMQ_EXPORT int zmq_poller_modify (void *poller, void *socket, short events);
47
- #ZMQ_EXPORT int zmq_poller_remove (void *poller, void *socket);
48
- #ZMQ_EXPORT int zmq_poller_wait (void *poller, zmq_poller_event_t *event, long timeout);
47
+ # ZMQ_EXPORT void *zmq_poller_new (void);
48
+ # ZMQ_EXPORT int zmq_poller_destroy (void **poller_p);
49
+ # ZMQ_EXPORT int zmq_poller_add (void *poller, void *socket, void *user_data, short events);
50
+ # ZMQ_EXPORT int zmq_poller_modify (void *poller, void *socket, short events);
51
+ # ZMQ_EXPORT int zmq_poller_remove (void *poller, void *socket);
52
+ # ZMQ_EXPORT int zmq_poller_wait (void *poller, zmq_poller_event_t *event, long timeout);
49
53
 
50
54
  # Gracefully attaches a function. If it's not available, this creates
51
55
  # a placeholder class method which, when called, simply raises
@@ -53,27 +57,26 @@ module CZTop
53
57
  def self.attach_function(function_nickname, function_name, *args)
54
58
  super
55
59
  rescue ::FFI::NotFoundError
56
- if $VERBOSE || $DEBUG
57
- warn "CZTop: The ZMQ function #{function_name}() is not available. Don't use CZTop::Poller."
58
- end
60
+ warn "CZTop: The ZMQ function #{function_name}() is not available. Don't use CZTop::Poller." if $VERBOSE || $DEBUG
59
61
  define_singleton_method(function_nickname) do |*|
60
- raise NotImplementedError, "compile ZMQ with --enable-drafts"
62
+ raise NotImplementedError, 'compile ZMQ with --enable-drafts'
61
63
  end
62
64
  end
63
65
 
64
66
  opts = {
65
- blocking: true # only necessary on MRI to deal with the GIL.
67
+ blocking: true # only necessary on MRI to deal with the GIL.
66
68
  }
67
69
  attach_function :poller_new, :zmq_poller_new, [], :pointer, **opts
68
70
  attach_function :poller_destroy, :zmq_poller_destroy,
69
- [:pointer], :int, **opts
71
+ [:pointer], :int, **opts
70
72
  attach_function :poller_add, :zmq_poller_add,
71
- [:pointer, :pointer, :pointer, :short], :int, **opts
73
+ %i[pointer pointer pointer short], :int, **opts
72
74
  attach_function :poller_modify, :zmq_poller_modify,
73
- [:pointer, :pointer, :short], :int, **opts
75
+ %i[pointer pointer short], :int, **opts
74
76
  attach_function :poller_remove, :zmq_poller_remove,
75
- [:pointer, :pointer], :int, **opts
77
+ %i[pointer pointer], :int, **opts
76
78
  attach_function :poller_wait, :zmq_poller_wait,
77
- [:pointer, :pointer, :long], :int, **opts
79
+ %i[pointer pointer long], :int, **opts
80
+
78
81
  end
79
82
  end