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
data/lib/cztop/proxy.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module CZTop
|
2
4
|
# Steerable proxy which switches messages between a frontend and a backend
|
3
5
|
# socket.
|
@@ -6,11 +8,12 @@ module CZTop
|
|
6
8
|
#
|
7
9
|
# @see http://api.zeromq.org/czmq3-0:zproxy
|
8
10
|
class Proxy
|
11
|
+
|
9
12
|
include ::CZMQ::FFI
|
10
13
|
|
11
14
|
# function pointer to the +zmonitor()+ function
|
12
15
|
ZPROXY_FPTR = ::CZMQ::FFI.ffi_libraries.each do |dl|
|
13
|
-
fptr = dl.find_function(
|
16
|
+
fptr = dl.find_function('zproxy')
|
14
17
|
break fptr if fptr
|
15
18
|
end
|
16
19
|
raise LoadError, "couldn't find zproxy()" if ZPROXY_FPTR.nil?
|
@@ -28,13 +31,15 @@ module CZTop
|
|
28
31
|
@actor.terminate
|
29
32
|
end
|
30
33
|
|
34
|
+
|
31
35
|
# Enable verbose logging of commands and activity.
|
32
36
|
# @return [void]
|
33
37
|
def verbose!
|
34
|
-
@actor <<
|
38
|
+
@actor << 'VERBOSE'
|
35
39
|
@actor.wait
|
36
40
|
end
|
37
41
|
|
42
|
+
|
38
43
|
# Returns a configurator object which you can use to configure the
|
39
44
|
# frontend socket.
|
40
45
|
# @return [Configurator] (memoized) frontend configurator
|
@@ -42,6 +47,7 @@ module CZTop
|
|
42
47
|
@frontend ||= Configurator.new(self, :frontend)
|
43
48
|
end
|
44
49
|
|
50
|
+
|
45
51
|
# Returns a configurator object which you can use to configure the backend
|
46
52
|
# socket.
|
47
53
|
# @return [Configurator] (memoized) backend configurator
|
@@ -49,54 +55,59 @@ module CZTop
|
|
49
55
|
@backend ||= Configurator.new(self, :backend)
|
50
56
|
end
|
51
57
|
|
58
|
+
|
52
59
|
# Captures all proxied messages and delivers them to a PULL socket bound
|
53
60
|
# to the specified endpoint.
|
54
61
|
# @note The PULL socket has to be bound before calling this method.
|
55
62
|
# @param endpoint [String] the endpoint to which the PULL socket is bound to
|
56
63
|
# @return [void]
|
57
64
|
def capture(endpoint)
|
58
|
-
@actor << [
|
65
|
+
@actor << ['CAPTURE', endpoint]
|
59
66
|
@actor.wait
|
60
67
|
end
|
61
68
|
|
69
|
+
|
62
70
|
# Pauses proxying of any messages.
|
63
71
|
# @note This causes any messages to be queued up and potentialy hit the
|
64
72
|
# high-water mark on the frontend or backend socket, causing messages to
|
65
73
|
# be dropped or writing applications to block.
|
66
74
|
# @return [void]
|
67
75
|
def pause
|
68
|
-
@actor <<
|
76
|
+
@actor << 'PAUSE'
|
69
77
|
@actor.wait
|
70
78
|
end
|
71
79
|
|
80
|
+
|
72
81
|
# Resume proxying of messages.
|
73
82
|
# @note This is only needed after a call to {#pause}, not to start the
|
74
83
|
# proxy. Proxying starts as soon as the frontend and backend sockets are
|
75
84
|
# properly attached.
|
76
85
|
# @return [void]
|
77
86
|
def resume
|
78
|
-
@actor <<
|
87
|
+
@actor << 'RESUME'
|
79
88
|
@actor.wait
|
80
89
|
end
|
81
90
|
|
91
|
+
|
82
92
|
# Used to configure the socket on one side of a {Proxy}.
|
83
93
|
class Configurator
|
94
|
+
|
84
95
|
# @return [Array<Symbol>] supported socket types
|
85
96
|
SOCKET_TYPES = %i[
|
86
97
|
PAIR PUB SUB REQ REP
|
87
98
|
DEALER ROUTER PULL PUSH
|
88
99
|
XPUB XSUB
|
89
|
-
]
|
100
|
+
].freeze
|
90
101
|
|
91
102
|
# @param proxy [Proxy] the proxy instance
|
92
103
|
# @param side [Symbol] :frontend or :backend
|
93
104
|
def initialize(proxy, side)
|
94
105
|
@proxy = proxy
|
95
|
-
@side
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
106
|
+
@side = case side
|
107
|
+
when :frontend then 'FRONTEND'
|
108
|
+
when :backend then 'BACKEND'
|
109
|
+
else raise ArgumentError, "invalid side: #{side.inspect}"
|
110
|
+
end
|
100
111
|
end
|
101
112
|
|
102
113
|
# @return [Proxy] the proxy this {Configurator} works on
|
@@ -111,27 +122,29 @@ module CZTop
|
|
111
122
|
# @raise [ArgumentError] if the given socket type is invalid
|
112
123
|
# @return [void]
|
113
124
|
def bind(socket_type, endpoint)
|
114
|
-
unless SOCKET_TYPES.include?(socket_type)
|
115
|
-
|
116
|
-
|
117
|
-
@proxy.actor << [ @side, socket_type.to_s, endpoint ]
|
125
|
+
raise ArgumentError, "invalid socket type: #{socket_type}" unless SOCKET_TYPES.include?(socket_type)
|
126
|
+
|
127
|
+
@proxy.actor << [@side, socket_type.to_s, endpoint]
|
118
128
|
@proxy.actor.wait
|
119
129
|
end
|
120
130
|
|
131
|
+
|
121
132
|
# Set ZAP domain for authentication.
|
122
133
|
# @param domain [String] the ZAP domain
|
123
134
|
def domain=(domain)
|
124
|
-
@proxy.actor << [
|
135
|
+
@proxy.actor << ['DOMAIN', @side, domain]
|
125
136
|
@proxy.actor.wait
|
126
137
|
end
|
127
138
|
|
139
|
+
|
128
140
|
# Configure PLAIN authentication on this socket.
|
129
141
|
# @note You'll have to use a {CZTop::Authenticator}.
|
130
142
|
def PLAIN_server!
|
131
|
-
@proxy.actor << [
|
143
|
+
@proxy.actor << ['PLAIN', @side]
|
132
144
|
@proxy.actor.wait
|
133
145
|
end
|
134
146
|
|
147
|
+
|
135
148
|
# Configure CURVE authentication on this socket.
|
136
149
|
# @note You'll have to use a {CZTop::Authenticator}.
|
137
150
|
# @param cert [Certificate] this server's certificate,
|
@@ -139,11 +152,13 @@ module CZTop
|
|
139
152
|
def CURVE_server!(cert)
|
140
153
|
public_key = cert.public_key
|
141
154
|
secret_key = cert.secret_key or
|
142
|
-
raise ArgumentError,
|
155
|
+
raise ArgumentError, 'no secret key in certificate'
|
143
156
|
|
144
|
-
@proxy.actor << [
|
157
|
+
@proxy.actor << ['CURVE', @side, public_key, secret_key]
|
145
158
|
@proxy.actor.wait
|
146
159
|
end
|
160
|
+
|
147
161
|
end
|
162
|
+
|
148
163
|
end
|
149
164
|
end
|
@@ -1,10 +1,12 @@
|
|
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
|
# but actually just pass through to methods of {Message} (which take
|
5
6
|
# a polymorphic reference, in Ruby as well as in C).
|
6
7
|
# @see http://api.zeromq.org/czmq3-0:zmsg
|
7
8
|
module SendReceiveMethods
|
9
|
+
|
8
10
|
# Sends a message.
|
9
11
|
#
|
10
12
|
# @param message [Message, String, Array<parts>] the message to send
|
@@ -20,6 +22,7 @@ module CZTop
|
|
20
22
|
self
|
21
23
|
end
|
22
24
|
|
25
|
+
|
23
26
|
# Receives a message.
|
24
27
|
#
|
25
28
|
# @return [Message]
|
@@ -31,5 +34,6 @@ module CZTop
|
|
31
34
|
def receive
|
32
35
|
Message.receive_from(self)
|
33
36
|
end
|
37
|
+
|
34
38
|
end
|
35
39
|
end
|
data/lib/cztop/socket/types.rb
CHANGED
@@ -1,29 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module CZTop
|
2
4
|
class Socket
|
5
|
+
|
3
6
|
# Socket types. Each constant in this namespace holds the type code used
|
4
7
|
# for the zsock_new() function.
|
5
8
|
module Types
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
|
10
|
+
PAIR = 0
|
11
|
+
PUB = 1
|
12
|
+
SUB = 2
|
13
|
+
REQ = 3
|
14
|
+
REP = 4
|
11
15
|
DEALER = 5
|
12
16
|
ROUTER = 6
|
13
|
-
PULL
|
14
|
-
PUSH
|
15
|
-
XPUB
|
16
|
-
XSUB
|
17
|
+
PULL = 7
|
18
|
+
PUSH = 8
|
19
|
+
XPUB = 9
|
20
|
+
XSUB = 10
|
17
21
|
STREAM = 11
|
18
22
|
SERVER = 12
|
19
23
|
CLIENT = 13
|
24
|
+
|
20
25
|
end
|
21
26
|
|
27
|
+
|
22
28
|
# All the available type codes, mapped to their Symbol equivalent.
|
23
29
|
# @return [Hash<Integer, Symbol>]
|
24
|
-
TypeNames =
|
25
|
-
|
26
|
-
|
30
|
+
TypeNames = Types.constants.to_h do |name|
|
31
|
+
i = Types.const_get(name)
|
32
|
+
[i, name]
|
33
|
+
end.freeze
|
34
|
+
|
27
35
|
|
28
36
|
# @param type [Symbol, Integer] type from {Types} or like +:PUB+
|
29
37
|
# @return [REQ, REP, PUSH, PULL, ... ] the new socket
|
@@ -33,75 +41,108 @@ module CZTop
|
|
33
41
|
def self.new_by_type(type)
|
34
42
|
case type
|
35
43
|
when Integer
|
36
|
-
type_code
|
37
|
-
type_name
|
38
|
-
raise ArgumentError,
|
44
|
+
type_code = type
|
45
|
+
type_name = TypeNames[type_code] or
|
46
|
+
raise ArgumentError, format('invalid type %p', type)
|
39
47
|
type_class = Socket.const_get(type_name)
|
40
48
|
when Symbol
|
41
|
-
type_code
|
49
|
+
type_code = Types.const_get(type)
|
42
50
|
type_class = Socket.const_get(type)
|
43
51
|
else
|
44
|
-
raise ArgumentError,
|
52
|
+
raise ArgumentError, format('invalid socket type: %p', type)
|
45
53
|
end
|
46
54
|
ffi_delegate = Zsock.new(type_code)
|
47
|
-
sock
|
55
|
+
sock = type_class.allocate
|
48
56
|
sock.attach_ffi_delegate(ffi_delegate)
|
49
57
|
sock
|
50
58
|
end
|
51
59
|
|
60
|
+
|
61
|
+
def initialize(endpoints = nil); end
|
62
|
+
|
63
|
+
|
52
64
|
# Client socket for the ZeroMQ Client-Server Pattern.
|
53
65
|
# @see http://rfc.zeromq.org/spec:41
|
54
66
|
class CLIENT < Socket
|
67
|
+
|
55
68
|
# @param endpoints [String] endpoints to connect to
|
56
69
|
def initialize(endpoints = nil)
|
70
|
+
super
|
71
|
+
|
57
72
|
attach_ffi_delegate(Zsock.new_client(endpoints))
|
58
73
|
end
|
74
|
+
|
59
75
|
end
|
60
76
|
|
77
|
+
|
61
78
|
# Server socket for the ZeroMQ Client-Server Pattern.
|
62
79
|
# @see http://rfc.zeromq.org/spec:41
|
63
80
|
class SERVER < Socket
|
81
|
+
|
64
82
|
# @param endpoints [String] endpoints to bind to
|
65
83
|
def initialize(endpoints = nil)
|
84
|
+
super
|
85
|
+
|
66
86
|
attach_ffi_delegate(Zsock.new_server(endpoints))
|
67
87
|
end
|
88
|
+
|
68
89
|
end
|
69
90
|
|
91
|
+
|
70
92
|
# Request socket for the ZeroMQ Request-Reply Pattern.
|
71
93
|
# @see http://rfc.zeromq.org/spec:28
|
72
94
|
class REQ < Socket
|
95
|
+
|
73
96
|
# @param endpoints [String] endpoints to connect to
|
74
97
|
def initialize(endpoints = nil)
|
98
|
+
super
|
99
|
+
|
75
100
|
attach_ffi_delegate(Zsock.new_req(endpoints))
|
76
101
|
end
|
102
|
+
|
77
103
|
end
|
78
104
|
|
105
|
+
|
79
106
|
# Reply socket for the ZeroMQ Request-Reply Pattern.
|
80
107
|
# @see http://rfc.zeromq.org/spec:28
|
81
108
|
class REP < Socket
|
109
|
+
|
82
110
|
# @param endpoints [String] endpoints to bind to
|
83
111
|
def initialize(endpoints = nil)
|
112
|
+
super
|
113
|
+
|
84
114
|
attach_ffi_delegate(Zsock.new_rep(endpoints))
|
85
115
|
end
|
116
|
+
|
86
117
|
end
|
87
118
|
|
119
|
+
|
88
120
|
# Dealer socket for the ZeroMQ Request-Reply Pattern.
|
89
121
|
# @see http://rfc.zeromq.org/spec:28
|
90
122
|
class DEALER < Socket
|
123
|
+
|
91
124
|
# @param endpoints [String] endpoints to connect to
|
92
125
|
def initialize(endpoints = nil)
|
126
|
+
super
|
127
|
+
|
93
128
|
attach_ffi_delegate(Zsock.new_dealer(endpoints))
|
94
129
|
end
|
130
|
+
|
95
131
|
end
|
96
132
|
|
133
|
+
|
97
134
|
# Router socket for the ZeroMQ Request-Reply Pattern.
|
98
135
|
# @see http://rfc.zeromq.org/spec:28
|
99
136
|
class ROUTER < Socket
|
137
|
+
|
100
138
|
# @param endpoints [String] endpoints to bind to
|
101
139
|
def initialize(endpoints = nil)
|
140
|
+
super
|
141
|
+
|
102
142
|
attach_ffi_delegate(Zsock.new_router(endpoints))
|
103
143
|
end
|
104
144
|
|
145
|
+
|
105
146
|
# Send a message to a specific receiver. This is a shorthand for when
|
106
147
|
# you send a message to a specific receiver with no hops in between.
|
107
148
|
# @param receiver [String] receiving peer's socket identity
|
@@ -110,32 +151,42 @@ module CZTop
|
|
110
151
|
# destroyed.
|
111
152
|
def send_to(receiver, message)
|
112
153
|
message = Message.coerce(message)
|
113
|
-
message.prepend
|
154
|
+
message.prepend '' # separator frame
|
114
155
|
message.prepend receiver # receiver envelope
|
115
156
|
self << message
|
116
157
|
end
|
158
|
+
|
117
159
|
end
|
118
160
|
|
161
|
+
|
119
162
|
# Publish socket for the ZeroMQ Publish-Subscribe Pattern.
|
120
163
|
# @see http://rfc.zeromq.org/spec:29
|
121
164
|
class PUB < Socket
|
165
|
+
|
122
166
|
# @param endpoints [String] endpoints to bind to
|
123
167
|
def initialize(endpoints = nil)
|
168
|
+
super
|
169
|
+
|
124
170
|
attach_ffi_delegate(Zsock.new_pub(endpoints))
|
125
171
|
end
|
172
|
+
|
126
173
|
end
|
127
174
|
|
175
|
+
|
128
176
|
# Subscribe socket for the ZeroMQ Publish-Subscribe Pattern.
|
129
177
|
# @see http://rfc.zeromq.org/spec:29
|
130
178
|
class SUB < Socket
|
179
|
+
|
131
180
|
# @param endpoints [String] endpoints to connect to
|
132
181
|
# @param subscription [String] what to subscribe to
|
133
182
|
def initialize(endpoints = nil, subscription = nil)
|
183
|
+
super(endpoints)
|
184
|
+
|
134
185
|
attach_ffi_delegate(Zsock.new_sub(endpoints, subscription))
|
135
186
|
end
|
136
187
|
|
137
188
|
# @return [String] subscription prefix to subscribe to everything
|
138
|
-
EVERYTHING =
|
189
|
+
EVERYTHING = ''
|
139
190
|
|
140
191
|
# Subscribes to the given prefix string.
|
141
192
|
# @param prefix [String] prefix string to subscribe to
|
@@ -144,86 +195,128 @@ module CZTop
|
|
144
195
|
ffi_delegate.set_subscribe(prefix)
|
145
196
|
end
|
146
197
|
|
198
|
+
|
147
199
|
# Unsubscribes from the given prefix.
|
148
200
|
# @param prefix [String] prefix string to unsubscribe from
|
149
201
|
# @return [void]
|
150
202
|
def unsubscribe(prefix)
|
151
203
|
ffi_delegate.set_unsubscribe(prefix)
|
152
204
|
end
|
205
|
+
|
153
206
|
end
|
154
207
|
|
208
|
+
|
155
209
|
# Extended publish socket for the ZeroMQ Publish-Subscribe Pattern.
|
156
210
|
# @see http://rfc.zeromq.org/spec:29
|
157
211
|
class XPUB < Socket
|
212
|
+
|
158
213
|
# @param endpoints [String] endpoints to bind to
|
159
214
|
def initialize(endpoints = nil)
|
215
|
+
super
|
216
|
+
|
160
217
|
attach_ffi_delegate(Zsock.new_xpub(endpoints))
|
161
218
|
end
|
219
|
+
|
162
220
|
end
|
163
221
|
|
222
|
+
|
164
223
|
# Extended subscribe socket for the ZeroMQ Publish-Subscribe Pattern.
|
165
224
|
# @see http://rfc.zeromq.org/spec:29
|
166
225
|
class XSUB < Socket
|
226
|
+
|
167
227
|
# @param endpoints [String] endpoints to connect to
|
168
228
|
def initialize(endpoints = nil)
|
229
|
+
super
|
230
|
+
|
169
231
|
attach_ffi_delegate(Zsock.new_xsub(endpoints))
|
170
232
|
end
|
233
|
+
|
171
234
|
end
|
172
235
|
|
236
|
+
|
173
237
|
# Push socket for the ZeroMQ Pipeline Pattern.
|
174
238
|
# @see http://rfc.zeromq.org/spec:30
|
175
239
|
class PUSH < Socket
|
240
|
+
|
176
241
|
# @param endpoints [String] endpoints to connect to
|
177
242
|
def initialize(endpoints = nil)
|
243
|
+
super
|
244
|
+
|
178
245
|
attach_ffi_delegate(Zsock.new_push(endpoints))
|
179
246
|
end
|
247
|
+
|
180
248
|
end
|
181
249
|
|
250
|
+
|
182
251
|
# Pull socket for the ZeroMQ Pipeline Pattern.
|
183
252
|
# @see http://rfc.zeromq.org/spec:30
|
184
253
|
class PULL < Socket
|
254
|
+
|
185
255
|
# @param endpoints [String] endpoints to bind to
|
186
256
|
def initialize(endpoints = nil)
|
257
|
+
super
|
258
|
+
|
187
259
|
attach_ffi_delegate(Zsock.new_pull(endpoints))
|
188
260
|
end
|
261
|
+
|
189
262
|
end
|
190
263
|
|
264
|
+
|
191
265
|
# Pair socket for inter-thread communication.
|
192
266
|
# @see http://rfc.zeromq.org/spec:31
|
193
267
|
class PAIR < Socket
|
268
|
+
|
194
269
|
# @param endpoints [String] endpoints to connect to
|
195
270
|
def initialize(endpoints = nil)
|
271
|
+
super
|
272
|
+
|
196
273
|
attach_ffi_delegate(Zsock.new_pair(endpoints))
|
197
274
|
end
|
275
|
+
|
198
276
|
end
|
199
277
|
|
278
|
+
|
200
279
|
# Stream socket for the native pattern. This is useful when
|
201
280
|
# communicating with a non-ZMQ peer over TCP.
|
202
281
|
# @see http://api.zeromq.org/4-2:zmq-socket#toc16
|
203
282
|
class STREAM < Socket
|
283
|
+
|
204
284
|
# @param endpoints [String] endpoints to connect to
|
205
285
|
def initialize(endpoints = nil)
|
286
|
+
super
|
287
|
+
|
206
288
|
attach_ffi_delegate(Zsock.new_stream(endpoints))
|
207
289
|
end
|
290
|
+
|
208
291
|
end
|
209
292
|
|
293
|
+
|
210
294
|
# Group-based pub/sub (vs topic-based). This is the publisher socket.
|
211
295
|
# @see https://github.com/zeromq/libzmq/pull/1727
|
212
296
|
class RADIO < Socket
|
297
|
+
|
213
298
|
# @param endpoints [String] endpoints to connect to
|
214
299
|
def initialize(endpoints = nil)
|
300
|
+
super
|
301
|
+
|
215
302
|
attach_ffi_delegate(Zsock.new_radio(endpoints))
|
216
303
|
end
|
304
|
+
|
217
305
|
end
|
218
306
|
|
307
|
+
|
219
308
|
# Group-based pub/sub (vs topic-based). This is the subscriber socket.
|
220
309
|
# @see https://github.com/zeromq/libzmq/pull/1727
|
221
310
|
class DISH < Socket
|
311
|
+
|
222
312
|
# @param endpoints [String] endpoints to connect to
|
223
313
|
def initialize(endpoints = nil)
|
314
|
+
super
|
315
|
+
|
224
316
|
attach_ffi_delegate(Zsock.new_dish(endpoints))
|
225
317
|
end
|
226
318
|
|
319
|
+
|
227
320
|
# Joins the given group.
|
228
321
|
# @param group [String] group to join, up to 15 characters
|
229
322
|
# @return [void]
|
@@ -232,9 +325,10 @@ module CZTop
|
|
232
325
|
# @raise [SystemCallError] in case of failure
|
233
326
|
def join(group)
|
234
327
|
rc = ffi_delegate.join(group)
|
235
|
-
raise_zmq_err(
|
328
|
+
raise_zmq_err(format('unable to join group %p', group)) if rc == -1
|
236
329
|
end
|
237
330
|
|
331
|
+
|
238
332
|
# Leaves the given group.
|
239
333
|
# @param group [String] group to leave
|
240
334
|
# @return [void]
|
@@ -242,26 +336,38 @@ module CZTop
|
|
242
336
|
# @raise [SystemCallError] in case of another failure
|
243
337
|
def leave(group)
|
244
338
|
rc = ffi_delegate.leave(group)
|
245
|
-
raise_zmq_err(
|
339
|
+
raise_zmq_err(format('unable to leave group %p', group)) if rc == -1
|
246
340
|
end
|
341
|
+
|
247
342
|
end
|
248
343
|
|
344
|
+
|
249
345
|
# Scatter/gather pattern.
|
250
346
|
# @see https://github.com/zeromq/libzmq/pull/1909
|
251
347
|
class SCATTER < Socket
|
348
|
+
|
252
349
|
# @param endpoints [String] endpoints to connect to
|
253
350
|
def initialize(endpoints = nil)
|
351
|
+
super
|
352
|
+
|
254
353
|
attach_ffi_delegate(Zsock.new_scatter(endpoints))
|
255
354
|
end
|
355
|
+
|
256
356
|
end
|
257
357
|
|
358
|
+
|
258
359
|
# Scatter/gather pattern.
|
259
360
|
# @see https://github.com/zeromq/libzmq/pull/1909
|
260
361
|
class GATHER < Socket
|
362
|
+
|
261
363
|
# @param endpoints [String] endpoints to connect to
|
262
364
|
def initialize(endpoints = nil)
|
365
|
+
super
|
366
|
+
|
263
367
|
attach_ffi_delegate(Zsock.new_gather(endpoints))
|
264
368
|
end
|
369
|
+
|
265
370
|
end
|
371
|
+
|
266
372
|
end
|
267
373
|
end
|
data/lib/cztop/socket.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module CZTop
|
2
4
|
# Represents a CZMQ::FFI::Zsock.
|
3
5
|
class Socket
|
6
|
+
|
4
7
|
include HasFFIDelegate
|
5
8
|
extend CZTop::HasFFIDelegate::ClassMethods
|
6
9
|
include ZsockOptions
|
@@ -21,6 +24,7 @@ module CZTop
|
|
21
24
|
cert.apply(self) # NOTE: desired: raises if no secret key in cert
|
22
25
|
end
|
23
26
|
|
27
|
+
|
24
28
|
# Enables CURVE security and makes this socket a CURVE client.
|
25
29
|
# @param client_cert [Certificate] client's certificate, to secure
|
26
30
|
# communication (and be authenticated by the server)
|
@@ -31,9 +35,7 @@ module CZTop
|
|
31
35
|
# which means it's not secret anymore
|
32
36
|
# @raise [SystemCallError] if there's no secret key in client_cert
|
33
37
|
def CURVE_client!(client_cert, server_cert)
|
34
|
-
if server_cert.secret_key
|
35
|
-
raise SecurityError, "server's secret key not secret"
|
36
|
-
end
|
38
|
+
raise SecurityError, "server's secret key not secret" if server_cert.secret_key
|
37
39
|
|
38
40
|
client_cert.apply(self) # NOTE: desired: raises if no secret key in cert
|
39
41
|
options.CURVE_serverkey = server_cert.public_key
|
@@ -41,30 +43,34 @@ module CZTop
|
|
41
43
|
|
42
44
|
# @!endgroup
|
43
45
|
|
46
|
+
|
44
47
|
# @return [String] last bound endpoint, if any
|
45
48
|
# @return [nil] if not bound
|
46
49
|
def last_endpoint
|
47
50
|
ffi_delegate.endpoint
|
48
51
|
end
|
49
52
|
|
53
|
+
|
50
54
|
# Connects to an endpoint.
|
51
55
|
# @param endpoint [String]
|
52
56
|
# @return [void]
|
53
57
|
# @raise [ArgumentError] if the endpoint is incorrect
|
54
58
|
def connect(endpoint)
|
55
|
-
rc = ffi_delegate.connect(
|
56
|
-
raise ArgumentError,
|
59
|
+
rc = ffi_delegate.connect('%s', :string, endpoint)
|
60
|
+
raise ArgumentError, format('incorrect endpoint: %p', endpoint) if rc == -1
|
57
61
|
end
|
58
62
|
|
63
|
+
|
59
64
|
# Disconnects from an endpoint.
|
60
65
|
# @param endpoint [String]
|
61
66
|
# @return [void]
|
62
67
|
# @raise [ArgumentError] if the endpoint is incorrect
|
63
68
|
def disconnect(endpoint)
|
64
|
-
rc = ffi_delegate.disconnect(
|
65
|
-
raise ArgumentError,
|
69
|
+
rc = ffi_delegate.disconnect('%s', :string, endpoint)
|
70
|
+
raise ArgumentError, format('incorrect endpoint: %p', endpoint) if rc == -1
|
66
71
|
end
|
67
72
|
|
73
|
+
|
68
74
|
# Closes and destroys the native socket.
|
69
75
|
# @return [void]
|
70
76
|
# @note Don't try to use it anymore afterwards.
|
@@ -83,30 +89,29 @@ module CZTop
|
|
83
89
|
# @return [void]
|
84
90
|
# @raise [SystemCallError] in case of failure
|
85
91
|
def bind(endpoint)
|
86
|
-
rc = ffi_delegate.bind(
|
87
|
-
raise_zmq_err(
|
88
|
-
@last_tcp_port = rc if rc
|
92
|
+
rc = ffi_delegate.bind('%s', :string, endpoint)
|
93
|
+
raise_zmq_err(format('unable to bind to %p', endpoint)) if rc == -1
|
94
|
+
@last_tcp_port = rc if rc.positive?
|
89
95
|
end
|
90
96
|
|
97
|
+
|
91
98
|
# Unbinds from an endpoint.
|
92
99
|
# @param endpoint [String]
|
93
100
|
# @return [void]
|
94
101
|
# @raise [ArgumentError] if the endpoint is incorrect
|
95
102
|
def unbind(endpoint)
|
96
|
-
rc = ffi_delegate.unbind(
|
97
|
-
raise ArgumentError,
|
103
|
+
rc = ffi_delegate.unbind('%s', :string, endpoint)
|
104
|
+
raise ArgumentError, format('incorrect endpoint: %p', endpoint) if rc == -1
|
98
105
|
end
|
99
106
|
|
107
|
+
|
100
108
|
# Inspects this {Socket}.
|
101
109
|
# @return [String] shows class, native address, and {#last_endpoint}
|
102
110
|
def inspect
|
103
|
-
|
104
|
-
self.class,
|
105
|
-
to_ptr.address,
|
106
|
-
last_endpoint
|
107
|
-
]
|
111
|
+
format('#<%s:0x%x last_endpoint=%p>', self.class, to_ptr.address, last_endpoint)
|
108
112
|
rescue Zsock::DestroyedError
|
109
|
-
|
113
|
+
format('#<%s: invalid>', self.class)
|
110
114
|
end
|
115
|
+
|
111
116
|
end
|
112
117
|
end
|