cztop 0.14.1 → 1.1.0.pre1

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 (47) 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/stable_api.yml +26 -0
  5. data/.rubocop.yml +175 -0
  6. data/CHANGES.md +9 -4
  7. data/Gemfile +3 -7
  8. data/README.md +19 -58
  9. data/ci/install-libczmq +22 -0
  10. data/ci/install-libzmq +22 -0
  11. data/cztop.gemspec +12 -13
  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 +25 -90
  44. data/.gitlab-ci.yml +0 -32
  45. data/Guardfile +0 -61
  46. data/Procfile +0 -3
  47. data/ci-scripts/install-deps +0 -8
data/lib/cztop/frame.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CZTop
2
4
  # Represents a CZMQ::FFI::Zframe, a part of a message.
3
5
  #
@@ -8,6 +10,7 @@ module CZTop
8
10
  #
9
11
  # @see http://api.zeromq.org/czmq3-0:zframe
10
12
  class Frame
13
+
11
14
  include HasFFIDelegate
12
15
  extend CZTop::HasFFIDelegate::ClassMethods
13
16
 
@@ -18,8 +21,8 @@ module CZTop
18
21
  self.content = content if content
19
22
  end
20
23
 
21
- FLAG_MORE = 1
22
- FLAG_REUSE = 2
24
+ FLAG_MORE = 1
25
+ FLAG_REUSE = 2
23
26
  FLAG_DONTWAIT = 4
24
27
 
25
28
  # Send {Message} to a {Socket}/{Actor}.
@@ -39,14 +42,14 @@ module CZTop
39
42
  # @raise [SystemCallError] if there was some error. In that case, the
40
43
  # native counterpart still exists and this {Frame} can be reused.
41
44
  def send_to(destination, more: false, reuse: false, dontwait: false)
42
- flags = 0
45
+ flags = 0
43
46
  flags |= FLAG_MORE if more
44
47
  flags |= FLAG_REUSE if reuse
45
48
  flags |= FLAG_DONTWAIT if dontwait
46
49
 
47
50
  # remember pointer, in case the zframe_t won't be destroyed
48
51
  zframe_ptr = ffi_delegate.to_ptr
49
- ret = CZMQ::FFI::Zframe.send(ffi_delegate, destination, flags)
52
+ ret = CZMQ::FFI::Zframe.send(ffi_delegate, destination, flags)
50
53
 
51
54
  if reuse || ret == -1
52
55
  # zframe_t hasn't been destroyed yet: avoid memory leak.
@@ -55,14 +58,13 @@ module CZTop
55
58
  end
56
59
 
57
60
  if ret == -1
58
- if dontwait && FFI.errno == Errno::EAGAIN::Errno
59
- raise IO::EAGAINWaitWritable
60
- end
61
+ raise IO::EAGAINWaitWritable if dontwait && FFI.errno == Errno::EAGAIN::Errno
61
62
 
62
63
  raise_zmq_err
63
64
  end
64
65
  end
65
66
 
67
+
66
68
  # Receive {Frame} from a {Socket}/{Actor}.
67
69
  # @note This is low-level. Consider just receiving a {Message}.
68
70
  # @return [Frame]
@@ -70,18 +72,20 @@ module CZTop
70
72
  from_ffi_delegate(CZMQ::FFI::Zframe.recv(source))
71
73
  end
72
74
 
75
+
73
76
  # @note This string is always binary. Use String#force_encoding if needed.
74
77
  # @return [String] content as string (encoding = Encoding::BINARY)
75
78
  def content
76
79
  ffi_delegate.data.read_string(size)
77
80
  end
78
- alias_method :to_s, :content
81
+ alias to_s content
79
82
 
80
83
  # @return [Boolean] if this {Frame} has zero-sized content
81
84
  def empty?
82
85
  size.zero?
83
86
  end
84
87
 
88
+
85
89
  # Sets new content of this {Frame}.
86
90
  # @param new_content [String]
87
91
  # @return [new_content]
@@ -92,12 +96,14 @@ module CZTop
92
96
  # NOTE: FFI::MemoryPointer will autorelease
93
97
  end
94
98
 
99
+
95
100
  # Duplicates a frame.
96
101
  # @return [Frame] new frame with same content
97
102
  def dup
98
103
  from_ffi_delegate(ffi_delegate.dup)
99
104
  end
100
105
 
106
+
101
107
  # @return [Boolean] if the MORE indicator is set
102
108
  # @note This happens when reading a frame from a {Socket} or using
103
109
  # {#more=}.
@@ -105,6 +111,7 @@ module CZTop
105
111
  ffi_delegate.more == 1
106
112
  end
107
113
 
114
+
108
115
  # Sets the MORE indicator.
109
116
  # @param indicator [Boolean]
110
117
  # @note This is NOT used when sending frame to socket.
@@ -114,6 +121,7 @@ module CZTop
114
121
  ffi_delegate.set_more(indicator ? 1 : 0)
115
122
  end
116
123
 
124
+
117
125
  # Compare to another frame.
118
126
  # @param other [Frame]
119
127
  # @return [Boolean] if this and the other frame have identical size and
@@ -151,10 +159,12 @@ module CZTop
151
159
  def routing_id=(new_routing_id)
152
160
  # need to raise manually, as FFI lacks this feature.
153
161
  # @see https://github.com/ffi/ffi/issues/473
154
- raise RangeError if new_routing_id < 0
162
+ raise RangeError if new_routing_id.negative?
163
+
155
164
  ffi_delegate.set_routing_id(new_routing_id)
156
165
  end
157
166
 
167
+
158
168
  # Gets the group (radio/dish pattern).
159
169
  # @note This is only set when the frame has been read from
160
170
  # a {CZTop::Socket::DISH} socket.
@@ -163,9 +173,11 @@ module CZTop
163
173
  def group
164
174
  group = ffi_delegate.group
165
175
  return nil if group.nil? || group.empty?
176
+
166
177
  group
167
178
  end
168
179
 
180
+
169
181
  # Sets a new group (radio/dish pattern).
170
182
  # @note This is used when the frame is sent via a {CZTop::Socket::RADIO}
171
183
  # socket.
@@ -174,7 +186,8 @@ module CZTop
174
186
  # @return [new_group]
175
187
  def group=(new_group)
176
188
  rc = ffi_delegate.set_group(new_group)
177
- raise_zmq_err("unable to set group to %p" % new_group) if rc == -1
189
+ raise_zmq_err(format('unable to set group to %p', new_group)) if rc == -1
178
190
  end
191
+
179
192
  end
180
193
  end
@@ -1,9 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'forwardable'
2
4
  require 'socket' # for SocketError
3
5
 
4
6
  # This module is used to attach the low-level objects of classes within the
5
7
  # CZMQ::FFI namespace (coming from the _czmq-ffi-gen_ gem) as delegates.
6
8
  module CZTop::HasFFIDelegate
9
+
7
10
  # @return [CZMQ::FFI::*] the attached delegate
8
11
  attr_reader :ffi_delegate
9
12
 
@@ -12,6 +15,7 @@ module CZTop::HasFFIDelegate
12
15
  @ffi_delegate.to_ptr
13
16
  end
14
17
 
18
+
15
19
  # Attaches an FFI delegate to the current (probably new) {CZTop} object.
16
20
  # @param ffi_delegate an instance of the corresponding class in the
17
21
  # CZMQ::FFI namespace
@@ -27,6 +31,7 @@ module CZTop::HasFFIDelegate
27
31
  @ffi_delegate = ffi_delegate
28
32
  end
29
33
 
34
+
30
35
  # Same as the counterpart in {ClassMethods}, but usable from within an
31
36
  # instance.
32
37
  # @see CZTop::FFIDelegate::ClassMethods#from_ffi_delegate
@@ -60,8 +65,10 @@ module CZTop::HasFFIDelegate
60
65
  end
61
66
  end
62
67
 
68
+
63
69
  # Some class methods related to FFI delegates.
64
70
  module ClassMethods
71
+
65
72
  include Forwardable
66
73
 
67
74
  # Delegate specified instance method to the registered FFI delegate.
@@ -73,6 +80,7 @@ module CZTop::HasFFIDelegate
73
80
  def_delegator(:@ffi_delegate, method)
74
81
  end
75
82
 
83
+
76
84
  # Allocates a new instance and attaches the FFI delegate to it. This is
77
85
  # useful if you already have an FFI delegate and need to attach it to a
78
86
  # fresh high-level object.
@@ -84,7 +92,9 @@ module CZTop::HasFFIDelegate
84
92
  def from_ffi_delegate(ffi_delegate)
85
93
  obj = allocate
86
94
  obj.attach_ffi_delegate(ffi_delegate)
87
- return obj
95
+ obj
88
96
  end
97
+
89
98
  end
99
+
90
100
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CZTop
2
4
  class Message
3
5
 
@@ -7,14 +9,17 @@ module CZTop
7
9
  frames.count
8
10
  end
9
11
 
12
+
10
13
  # Access to this {Message}'s {Frame}s.
11
14
  # @return [FramesAccessor]
12
15
  def frames
13
16
  FramesAccessor.new(self)
14
17
  end
15
18
 
19
+
16
20
  # Used to access a {Message}'s {Frame}s.
17
21
  class FramesAccessor
22
+
18
23
  include Enumerable
19
24
 
20
25
  # @param message [Message]
@@ -22,24 +27,29 @@ module CZTop
22
27
  @message = message
23
28
  end
24
29
 
30
+
25
31
  # Returns the last frame of this message.
26
32
  # @return [Frame] first frame of Message
27
33
  # @return [nil] if there are no frames
28
34
  def first
29
35
  first = @message.ffi_delegate.first
30
36
  return nil if first.null?
37
+
31
38
  Frame.from_ffi_delegate(first)
32
39
  end
33
40
 
41
+
34
42
  # Returns the last frame of this message.
35
43
  # @return [Frame] last {Frame} of {Message}
36
44
  # @return [nil] if there are no frames
37
45
  def last
38
46
  last = @message.ffi_delegate.last
39
47
  return nil if last.null?
48
+
40
49
  Frame.from_ffi_delegate(last)
41
50
  end
42
51
 
52
+
43
53
  # Index access to a frame/frames of this message, just like with an
44
54
  # array.
45
55
  # @overload [](index)
@@ -56,6 +66,7 @@ module CZTop
56
66
  end
57
67
  end
58
68
 
69
+
59
70
  # Yields all frames for this message to the given block.
60
71
  # @note Not thread safe.
61
72
  # @yieldparam frame [Frame]
@@ -63,12 +74,15 @@ module CZTop
63
74
  def each
64
75
  first = first()
65
76
  return unless first
77
+
66
78
  yield first
67
- while frame = @message.ffi_delegate.next and not frame.null?
79
+ while (frame = @message.ffi_delegate.next) && !frame.null?
68
80
  yield Frame.from_ffi_delegate(frame)
69
81
  end
70
- return self
82
+ self
71
83
  end
84
+
72
85
  end
86
+
73
87
  end
74
88
  end
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