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.
- checksums.yaml +4 -4
- data/.github/workflows/coverage.yml +20 -0
- data/.github/workflows/draft_api.yml +27 -0
- data/.github/workflows/stable_api.yml +26 -0
- data/.rubocop.yml +175 -0
- data/CHANGES.md +9 -4
- data/Gemfile +3 -7
- data/README.md +19 -58
- data/ci/install-libczmq +22 -0
- data/ci/install-libzmq +22 -0
- data/cztop.gemspec +12 -13
- data/lib/cztop/actor.rb +55 -26
- data/lib/cztop/authenticator.rb +18 -9
- data/lib/cztop/beacon.rb +22 -10
- data/lib/cztop/cert_store.rb +8 -2
- data/lib/cztop/certificate.rb +47 -18
- data/lib/cztop/config/comments.rb +14 -3
- data/lib/cztop/config/serialization.rb +25 -5
- data/lib/cztop/config/traversing.rb +44 -13
- data/lib/cztop/config.rb +23 -9
- data/lib/cztop/frame.rb +23 -10
- data/lib/cztop/has_ffi_delegate.rb +11 -1
- data/lib/cztop/message/frames.rb +16 -2
- data/lib/cztop/message.rb +36 -22
- data/lib/cztop/metadata.rb +35 -24
- data/lib/cztop/monitor.rb +14 -5
- data/lib/cztop/poller/aggregated.rb +31 -15
- data/lib/cztop/poller/zmq.rb +25 -22
- data/lib/cztop/poller/zpoller.rb +18 -6
- data/lib/cztop/poller.rb +43 -18
- data/lib/cztop/polymorphic_zsock_methods.rb +6 -1
- data/lib/cztop/proxy.rb +34 -19
- data/lib/cztop/send_receive_methods.rb +5 -1
- data/lib/cztop/socket/types.rb +128 -22
- data/lib/cztop/socket.rb +23 -18
- data/lib/cztop/version.rb +5 -1
- data/lib/cztop/z85/padded.rb +12 -3
- data/lib/cztop/z85/pipe.rb +40 -17
- data/lib/cztop/z85.rb +17 -6
- data/lib/cztop/zap.rb +57 -32
- data/lib/cztop/zsock_options.rb +155 -122
- data/lib/cztop.rb +2 -1
- metadata +25 -90
- data/.gitlab-ci.yml +0 -32
- data/Guardfile +0 -61
- data/Procfile +0 -3
- data/ci-scripts/install-deps +0 -8
@@ -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
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
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
|
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
|
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
|
-
|
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
|
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
|
data/lib/cztop/poller/zmq.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
|
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
|
12
|
-
lib_dirs
|
13
|
-
lib_dirs
|
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)
|
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)
|
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,
|
62
|
+
raise NotImplementedError, 'compile ZMQ with --enable-drafts'
|
61
63
|
end
|
62
64
|
end
|
63
65
|
|
64
66
|
opts = {
|
65
|
-
blocking: true
|
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
|
-
|
71
|
+
[:pointer], :int, **opts
|
70
72
|
attach_function :poller_add, :zmq_poller_add,
|
71
|
-
|
73
|
+
%i[pointer pointer pointer short], :int, **opts
|
72
74
|
attach_function :poller_modify, :zmq_poller_modify,
|
73
|
-
|
75
|
+
%i[pointer pointer short], :int, **opts
|
74
76
|
attach_function :poller_remove, :zmq_poller_remove,
|
75
|
-
|
77
|
+
%i[pointer pointer], :int, **opts
|
76
78
|
attach_function :poller_wait, :zmq_poller_wait,
|
77
|
-
|
79
|
+
%i[pointer pointer long], :int, **opts
|
80
|
+
|
78
81
|
end
|
79
82
|
end
|
data/lib/cztop/poller/zpoller.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module CZTop
|
2
4
|
# This is the trivial poller based on zpoller. It only supports polling
|
3
5
|
# for readability, but it also supports doing that on CLIENT/SERVER sockets,
|
@@ -5,6 +7,7 @@ module CZTop
|
|
5
7
|
#
|
6
8
|
# @see http://api.zeromq.org/czmq3-0:zpoller
|
7
9
|
class Poller::ZPoller
|
10
|
+
|
8
11
|
include HasFFIDelegate
|
9
12
|
extend CZTop::HasFFIDelegate::ClassMethods
|
10
13
|
include ::CZMQ::FFI
|
@@ -14,24 +17,26 @@ module CZTop
|
|
14
17
|
# @param readers [Socket, Actor] any additional sockets to poll for input
|
15
18
|
def initialize(reader, *readers)
|
16
19
|
@sockets = {} # to keep references and return same instances
|
17
|
-
ptr
|
18
|
-
|
19
|
-
|
20
|
+
ptr = Zpoller.new(reader,
|
21
|
+
*readers.flat_map { |r| [:pointer, r] },
|
22
|
+
:pointer, nil)
|
20
23
|
attach_ffi_delegate(ptr)
|
21
24
|
remember_socket(reader)
|
22
25
|
readers.each { |r| remember_socket(r) }
|
23
26
|
end
|
24
27
|
|
28
|
+
|
25
29
|
# Adds another reader socket to the poller.
|
26
30
|
# @param reader [Socket, Actor] socket to poll for input
|
27
31
|
# @return [void]
|
28
32
|
# @raise [SystemCallError] if this fails
|
29
33
|
def add(reader)
|
30
34
|
rc = ffi_delegate.add(reader)
|
31
|
-
raise_zmq_err(
|
35
|
+
raise_zmq_err(format('unable to add socket %p', reader)) if rc == -1
|
32
36
|
remember_socket(reader)
|
33
37
|
end
|
34
38
|
|
39
|
+
|
35
40
|
# Removes a reader socket from the poller.
|
36
41
|
# @param reader [Socket, Actor] socket to remove
|
37
42
|
# @return [void]
|
@@ -40,10 +45,11 @@ module CZTop
|
|
40
45
|
# @raise [SystemCallError] if this fails for another reason
|
41
46
|
def remove(reader)
|
42
47
|
rc = ffi_delegate.remove(reader)
|
43
|
-
raise_zmq_err(
|
48
|
+
raise_zmq_err(format('unable to remove socket %p', reader)) if rc == -1
|
44
49
|
forget_socket(reader)
|
45
50
|
end
|
46
51
|
|
52
|
+
|
47
53
|
# Waits and returns the first socket that becomes readable.
|
48
54
|
# @param timeout [Integer] how long to wait in ms, or 0 to avoid
|
49
55
|
# blocking, or -1 to wait indefinitely
|
@@ -54,11 +60,13 @@ module CZTop
|
|
54
60
|
ptr = ffi_delegate.wait(timeout)
|
55
61
|
if ptr.null?
|
56
62
|
raise Interrupt if ffi_delegate.terminated
|
63
|
+
|
57
64
|
return nil
|
58
65
|
end
|
59
|
-
|
66
|
+
socket_by_ptr(ptr)
|
60
67
|
end
|
61
68
|
|
69
|
+
|
62
70
|
# Tells the zpoller to ignore interrupts. By default, {#wait} will return
|
63
71
|
# immediately if it detects an interrupt (when +zsys_interrupted+ is set
|
64
72
|
# to something other than zero). Calling this method will supress this
|
@@ -68,6 +76,7 @@ module CZTop
|
|
68
76
|
ffi_delegate.ignore_interrupts
|
69
77
|
end
|
70
78
|
|
79
|
+
|
71
80
|
# By default the poller stops if the process receives a SIGINT or SIGTERM
|
72
81
|
# signal. This makes it impossible to shut-down message based architectures
|
73
82
|
# like zactors. This method lets you switch off break handling. The default
|
@@ -91,6 +100,7 @@ module CZTop
|
|
91
100
|
@sockets[socket.to_ptr.to_i] = socket
|
92
101
|
end
|
93
102
|
|
103
|
+
|
94
104
|
# Forgets the socket because it has been removed from the poller.
|
95
105
|
# @param socket [Socket, Actor] the socket instance to forget
|
96
106
|
# @return [void]
|
@@ -98,6 +108,7 @@ module CZTop
|
|
98
108
|
@sockets.delete(socket.to_ptr.to_i)
|
99
109
|
end
|
100
110
|
|
111
|
+
|
101
112
|
# Gets the previously remembered socket associated to the given pointer.
|
102
113
|
# @param ptr [FFI::Pointer] the pointer to a socket
|
103
114
|
# @return [Socket, Actor] the socket associated to the given pointer
|
@@ -109,5 +120,6 @@ module CZTop
|
|
109
120
|
# it ever returns a wrong pointer.
|
110
121
|
raise_zmq_err("no socket known for pointer #{ptr.inspect}")
|
111
122
|
end
|
123
|
+
|
112
124
|
end
|
113
125
|
end
|
data/lib/cztop/poller.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module CZTop
|
2
4
|
# A non-trivial socket poller.
|
3
5
|
#
|
@@ -9,23 +11,25 @@ module CZTop
|
|
9
11
|
# * +zpoller+ can only poll for readability
|
10
12
|
#
|
11
13
|
class Poller
|
14
|
+
|
12
15
|
include ::CZMQ::FFI
|
13
16
|
|
14
17
|
# @param readers [Socket, Actor] sockets to poll for input
|
15
18
|
def initialize(*readers)
|
16
|
-
@sockets
|
17
|
-
@events
|
19
|
+
@sockets = {} # needed to return the same socket objects
|
20
|
+
@events = {} # event masks for each socket
|
18
21
|
@poller_ptr = ZMQ.poller_new
|
19
22
|
ObjectSpace.define_finalizer(@poller_ptr,
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
23
|
+
proc do
|
24
|
+
ptr_ptr = ::FFI::MemoryPointer.new :pointer
|
25
|
+
ptr_ptr.write_pointer(@poller_ptr)
|
26
|
+
ZMQ.poller_destroy(ptr_ptr)
|
27
|
+
end)
|
25
28
|
@event_ptr = FFI::MemoryPointer.new(ZMQ::PollerEvent)
|
26
29
|
readers.each { |r| add_reader(r) }
|
27
30
|
end
|
28
31
|
|
32
|
+
|
29
33
|
# Adds a socket to be polled for readability.
|
30
34
|
# @param socket [Socket, Actor] the socket
|
31
35
|
# @param events [Integer] bitwise-OR'd events you're interested in (see
|
@@ -34,11 +38,12 @@ module CZTop
|
|
34
38
|
# @raise [ArgumentError] if it's not a socket
|
35
39
|
def add(socket, events)
|
36
40
|
ptr = ptr_for_socket(socket)
|
37
|
-
rc
|
41
|
+
rc = ZMQ.poller_add(@poller_ptr, ptr, nil, events)
|
38
42
|
HasFFIDelegate.raise_zmq_err if rc == -1
|
39
43
|
remember_socket(socket, events)
|
40
44
|
end
|
41
45
|
|
46
|
+
|
42
47
|
# Convenience method to register a socket for readability. See {#add}.
|
43
48
|
# @param socket [Socket, Actor] the socket
|
44
49
|
# @return [void]
|
@@ -46,6 +51,7 @@ module CZTop
|
|
46
51
|
add(socket, ZMQ::POLLIN)
|
47
52
|
end
|
48
53
|
|
54
|
+
|
49
55
|
# Convenience method to register a socket for writability. See {#add}.
|
50
56
|
# @param socket [Socket, Actor] the socket
|
51
57
|
# @return [void]
|
@@ -53,6 +59,7 @@ module CZTop
|
|
53
59
|
add(socket, ZMQ::POLLOUT)
|
54
60
|
end
|
55
61
|
|
62
|
+
|
56
63
|
# Modifies the events of interest for the given socket.
|
57
64
|
# @param socket [Socket, Actor] the socket
|
58
65
|
# @param events [Integer] events you're interested in (see constants in
|
@@ -61,11 +68,12 @@ module CZTop
|
|
61
68
|
# @raise [ArgumentError] if it's not a socket
|
62
69
|
def modify(socket, events)
|
63
70
|
ptr = ptr_for_socket(socket)
|
64
|
-
rc
|
71
|
+
rc = ZMQ.poller_modify(@poller_ptr, ptr, events)
|
65
72
|
HasFFIDelegate.raise_zmq_err if rc == -1
|
66
73
|
remember_socket(socket, events)
|
67
74
|
end
|
68
75
|
|
76
|
+
|
69
77
|
# Removes a previously registered socket. Won't raise if you're
|
70
78
|
# trying to remove a socket that's not registered.
|
71
79
|
# @param socket [Socket, Actor] the socket
|
@@ -73,11 +81,12 @@ module CZTop
|
|
73
81
|
# @raise [ArgumentError] if it's not a socket
|
74
82
|
def remove(socket)
|
75
83
|
ptr = ptr_for_socket(socket)
|
76
|
-
rc
|
84
|
+
rc = ZMQ.poller_remove(@poller_ptr, ptr)
|
77
85
|
HasFFIDelegate.raise_zmq_err if rc == -1
|
78
86
|
forget_socket(socket)
|
79
87
|
end
|
80
88
|
|
89
|
+
|
81
90
|
# Removes a reader socket that was registered for readability only.
|
82
91
|
#
|
83
92
|
# @param socket [Socket, Actor] the socket
|
@@ -88,9 +97,10 @@ module CZTop
|
|
88
97
|
remove(socket)
|
89
98
|
return
|
90
99
|
end
|
91
|
-
raise ArgumentError,
|
100
|
+
raise ArgumentError, format('not registered for readability only: %p', socket)
|
92
101
|
end
|
93
102
|
|
103
|
+
|
94
104
|
# Removes a reader socket that was registered for writability only.
|
95
105
|
#
|
96
106
|
# @param socket [Socket, Actor] the socket
|
@@ -101,9 +111,10 @@ module CZTop
|
|
101
111
|
remove(socket)
|
102
112
|
return
|
103
113
|
end
|
104
|
-
raise ArgumentError,
|
114
|
+
raise ArgumentError, format('not registered for writability only: %p', socket)
|
105
115
|
end
|
106
116
|
|
117
|
+
|
107
118
|
# Waits for registered sockets to become readable or writable, depending
|
108
119
|
# on what you're interested in.
|
109
120
|
#
|
@@ -116,7 +127,7 @@ module CZTop
|
|
116
127
|
rc = ZMQ.poller_wait(@poller_ptr, @event_ptr, timeout)
|
117
128
|
if rc == -1
|
118
129
|
case CZMQ::FFI::Errors.errno
|
119
|
-
|
130
|
+
# NOTE: ETIMEDOUT for backwards compatibility, although this API is
|
120
131
|
# still DRAFT.
|
121
132
|
when Errno::EAGAIN::Errno, Errno::ETIMEDOUT::Errno
|
122
133
|
return nil
|
@@ -124,9 +135,10 @@ module CZTop
|
|
124
135
|
HasFFIDelegate.raise_zmq_err
|
125
136
|
end
|
126
137
|
end
|
127
|
-
|
138
|
+
Event.new(self, @event_ptr)
|
128
139
|
end
|
129
140
|
|
141
|
+
|
130
142
|
# Simpler version of {#wait}, which just returns the first socket of
|
131
143
|
# interest, if any. This is useful if you either have only reader sockets,
|
132
144
|
# or only have writer sockets.
|
@@ -140,27 +152,30 @@ module CZTop
|
|
140
152
|
return event.socket if event
|
141
153
|
end
|
142
154
|
|
155
|
+
|
143
156
|
# @param ptr [FFI::Pointer] pointer to the socket
|
144
157
|
# @return [Socket, Actor] socket corresponding to given pointer
|
145
158
|
# @raise [ArgumentError] if pointer is not known
|
146
159
|
def socket_for_ptr(ptr)
|
147
160
|
@sockets[ptr.to_i] or
|
148
|
-
raise ArgumentError,
|
161
|
+
raise ArgumentError, format('no socket known for pointer %p', ptr)
|
149
162
|
end
|
150
163
|
|
164
|
+
|
151
165
|
# @return [Array<CZTop::Socket>] all sockets registered with this poller
|
152
166
|
# @note The actual events registered for each sockets don't matter.
|
153
167
|
def sockets
|
154
168
|
@sockets.values
|
155
169
|
end
|
156
170
|
|
171
|
+
|
157
172
|
# Returns the event mask for the given, registered socket.
|
158
173
|
# @param socket [Socket, Actor] which socket's events to return
|
159
174
|
# @return [Integer] event mask for the given socket
|
160
175
|
# @raise [ArgumentError] if socket is not registered
|
161
176
|
def event_mask_for_socket(socket)
|
162
177
|
@events[socket] or
|
163
|
-
raise ArgumentError,
|
178
|
+
raise ArgumentError, format('no event mask known for socket %p', socket)
|
164
179
|
end
|
165
180
|
|
166
181
|
private
|
@@ -170,17 +185,20 @@ module CZTop
|
|
170
185
|
# @raise [ArgumentError] if argument is not a socket
|
171
186
|
def ptr_for_socket(socket)
|
172
187
|
raise ArgumentError unless socket.is_a?(Socket) || socket.is_a?(Actor)
|
188
|
+
|
173
189
|
Zsock.resolve(socket)
|
174
190
|
end
|
175
191
|
|
192
|
+
|
176
193
|
# Keeps a reference to the given socket, and remembers its event mask.
|
177
194
|
# @param socket [Socket, Actor] the socket
|
178
195
|
# @param events [Integer] the event mask
|
179
196
|
def remember_socket(socket, events)
|
180
197
|
@sockets[ptr_for_socket(socket).to_i] = socket
|
181
|
-
@events[socket]
|
198
|
+
@events[socket] = events
|
182
199
|
end
|
183
200
|
|
201
|
+
|
184
202
|
# Discards the referencel to the given socket, and forgets its event mask.
|
185
203
|
# @param socket [Socket, Actor] the socket
|
186
204
|
def forget_socket(socket)
|
@@ -188,33 +206,40 @@ module CZTop
|
|
188
206
|
@events.delete(socket)
|
189
207
|
end
|
190
208
|
|
209
|
+
|
191
210
|
# Represents an event returned by {CZTop::Poller#wait}. This is useful to
|
192
211
|
# find out whether the associated socket is now readable or writable, in
|
193
212
|
# case you're interested in both. For a simpler variant, check out
|
194
213
|
# {CZTop::Poller#simple_wait}.
|
195
214
|
class Event
|
215
|
+
|
196
216
|
# @param poller [CZTop::Poller] the poller instance
|
197
217
|
# @param event_ptr [FFI::Pointer] pointer to the memory allocated for
|
198
218
|
# the event's data (a +zmq_poller_event_t+)
|
199
219
|
def initialize(poller, event_ptr)
|
200
|
-
@poller
|
220
|
+
@poller = poller
|
201
221
|
@poller_event = ZMQ::PollerEvent.new(event_ptr)
|
202
222
|
end
|
203
223
|
|
224
|
+
|
204
225
|
# @return [Socket, Actor] the associated socket
|
205
226
|
def socket
|
206
227
|
@socket ||= @poller.socket_for_ptr(@poller_event[:socket])
|
207
228
|
end
|
208
229
|
|
230
|
+
|
209
231
|
# @return [Boolean] whether it's readable
|
210
232
|
def readable?
|
211
233
|
@poller_event.readable?
|
212
234
|
end
|
213
235
|
|
236
|
+
|
214
237
|
# @return [Boolean] whether it's writable
|
215
238
|
def writable?
|
216
239
|
@poller_event.writable?
|
217
240
|
end
|
241
|
+
|
218
242
|
end
|
243
|
+
|
219
244
|
end
|
220
245
|
end
|
@@ -1,24 +1,29 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
module CZTop
|
3
4
|
# These are methods that can be used on a {Socket} as well as an {Actor}.
|
4
5
|
# @see http://api.zeromq.org/czmq3-0:zsock
|
5
6
|
module PolymorphicZsockMethods
|
7
|
+
|
6
8
|
# Sends a signal.
|
7
9
|
# @param status [Integer] signal (0-255)
|
8
10
|
def signal(status = 0)
|
9
11
|
::CZMQ::FFI::Zsock.signal(ffi_delegate, status)
|
10
12
|
end
|
11
13
|
|
14
|
+
|
12
15
|
# Waits for a signal.
|
13
16
|
# @return [Integer] the received signal
|
14
17
|
def wait
|
15
18
|
::CZMQ::FFI::Zsock.wait(ffi_delegate)
|
16
19
|
end
|
17
20
|
|
21
|
+
|
18
22
|
# Set socket to use unbounded pipes (HWM=0); use this in cases when you are
|
19
23
|
# totally certain the message volume can fit in memory.
|
20
24
|
def set_unbounded
|
21
25
|
::CZMQ::FFI::Zsock.set_unbounded(ffi_delegate)
|
22
26
|
end
|
27
|
+
|
23
28
|
end
|
24
29
|
end
|