zmqmachine 0.6.0 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +15 -0
- data/AUTHORS.txt +3 -0
- data/History.txt +19 -0
- data/examples/fake_ftp.rb +9 -1
- data/examples/one_handed_ping_pong.rb +2 -1
- data/examples/ping_pong.rb +2 -2
- data/examples/pub_sub.rb +10 -4
- data/examples/pubsub_forwarder.rb +8 -3
- data/examples/throttled_ping_pong.rb +2 -2
- data/lib/zm/configuration.rb +129 -0
- data/lib/zm/device.rb +4 -0
- data/lib/zm/device/configuration.rb +24 -0
- data/lib/zm/{devices → device}/forwarder.rb +48 -46
- data/lib/zm/{devices → device}/queue.rb +63 -44
- data/lib/zm/log_client.rb +2 -2
- data/lib/zm/log_server.rb +68 -0
- data/lib/zm/reactor.rb +42 -29
- data/lib/zm/server.rb +4 -0
- data/lib/zm/server/base.rb +139 -0
- data/lib/zm/server/configuration.rb +53 -0
- data/lib/zm/server/pair.rb +23 -0
- data/lib/zm/server/pub.rb +23 -0
- data/lib/zm/server/pull.rb +24 -0
- data/lib/zm/server/push.rb +23 -0
- data/lib/zm/server/rep.rb +42 -0
- data/lib/zm/server/req.rb +41 -0
- data/lib/zm/server/routing_envelope.rb +26 -0
- data/lib/zm/server/sub.rb +40 -0
- data/lib/zm/sockets.rb +1 -1
- data/lib/zm/sockets/base.rb +3 -12
- data/lib/zm/sockets/envelope_help.rb +49 -0
- data/lib/zm/sockets/pair.rb +0 -1
- data/lib/zm/sockets/pub.rb +0 -1
- data/lib/zm/sockets/rep.rb +45 -0
- data/lib/zm/sockets/req.rb +46 -1
- data/lib/zm/sockets/sub.rb +0 -1
- data/lib/zm/timers.rb +26 -13
- data/lib/zmqmachine.rb +1 -1
- data/version.txt +1 -1
- data/zmqmachine.gemspec +6 -6
- metadata +90 -91
- data/lib/zm/devices.rb +0 -4
- data/lib/zm/sockets/xrep.rb +0 -86
- data/lib/zm/sockets/xreq.rb +0 -86
@@ -0,0 +1,53 @@
|
|
1
|
+
|
2
|
+
module ZMQMachine
|
3
|
+
module Server
|
4
|
+
ZMQMachine::ConfigClassMaker.create_class('Configuration',
|
5
|
+
%w( on_read bind connect endpoint topic hwm linger extra reactor ),
|
6
|
+
ZMQMachine::Configuration,
|
7
|
+
ZMQMachine::Server)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
#module ZMQMachine
|
12
|
+
#
|
13
|
+
# module Server
|
14
|
+
#
|
15
|
+
# class Configuration
|
16
|
+
# Fields = %w( on_read bind connect endpoint topic hwm linger extra reactor name context log_endpoint exception_handler )
|
17
|
+
#
|
18
|
+
# # Creates a Configuration object from another object that conforms
|
19
|
+
# # to the Configuration protocol.
|
20
|
+
# #
|
21
|
+
# def self.create_from(other_config)
|
22
|
+
# config = new
|
23
|
+
# Fields.each do |name|
|
24
|
+
# config.send("#{name}", other_config.send(name.to_sym)) if config.respond_to?(name.to_sym)
|
25
|
+
# end
|
26
|
+
# config
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# def initialize(&blk)
|
30
|
+
# instance_eval(&blk) if block_given?
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# Fields.each do |name|
|
34
|
+
# code = <<-code
|
35
|
+
# def #{ name } (value = nil)
|
36
|
+
# if value
|
37
|
+
# @#{name} = value
|
38
|
+
# else
|
39
|
+
# @#{name}
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# def #{ name }=(value)
|
44
|
+
# @#{name} = value
|
45
|
+
# end
|
46
|
+
# code
|
47
|
+
#
|
48
|
+
# class_eval code
|
49
|
+
# end
|
50
|
+
# end # class Configuration
|
51
|
+
#
|
52
|
+
# end # Server
|
53
|
+
#end # ZMQMachine
|
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
module ZMQMachine
|
3
|
+
|
4
|
+
module Server
|
5
|
+
|
6
|
+
module Pair
|
7
|
+
include Base
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def allocate_socket
|
12
|
+
@socket = @reactor.pair_socket(self)
|
13
|
+
end
|
14
|
+
|
15
|
+
def register_for_events socket
|
16
|
+
@reactor.register_readable socket
|
17
|
+
@reactor.register_writable socket
|
18
|
+
end
|
19
|
+
|
20
|
+
end # module Pair
|
21
|
+
|
22
|
+
end # module Server
|
23
|
+
end # ZMQMachine
|
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
module ZMQMachine
|
3
|
+
|
4
|
+
module Server
|
5
|
+
|
6
|
+
module PUB
|
7
|
+
include Base
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def allocate_socket
|
12
|
+
@socket = @reactor.pub_socket(self)
|
13
|
+
end
|
14
|
+
|
15
|
+
def register_for_events socket
|
16
|
+
@reactor.deregister_readable socket
|
17
|
+
@reactor.deregister_writable socket
|
18
|
+
end
|
19
|
+
|
20
|
+
end # module PUB
|
21
|
+
|
22
|
+
end # module Server
|
23
|
+
end # ZMQMachine
|
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
module ZMQMachine
|
3
|
+
|
4
|
+
module Server
|
5
|
+
|
6
|
+
module PULL
|
7
|
+
include Base
|
8
|
+
|
9
|
+
def write messages
|
10
|
+
# no op
|
11
|
+
close messages
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def allocate_socket
|
18
|
+
@socket = @reactor.pull_socket(self)
|
19
|
+
end
|
20
|
+
|
21
|
+
end # module PULL
|
22
|
+
|
23
|
+
end # module Server
|
24
|
+
end # ZMQMachine
|
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
module ZMQMachine
|
3
|
+
|
4
|
+
module Server
|
5
|
+
|
6
|
+
module PUSH
|
7
|
+
include Base
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def allocate_socket
|
12
|
+
@socket = @reactor.push_socket(self)
|
13
|
+
end
|
14
|
+
|
15
|
+
def register_for_events socket
|
16
|
+
@reactor.deregister_readable socket
|
17
|
+
@reactor.deregister_writable socket
|
18
|
+
end
|
19
|
+
|
20
|
+
end # module PUSH
|
21
|
+
|
22
|
+
end # module Servers
|
23
|
+
end # ZMQMachine
|
@@ -0,0 +1,42 @@
|
|
1
|
+
|
2
|
+
module ZMQMachine
|
3
|
+
|
4
|
+
module Server
|
5
|
+
|
6
|
+
module REP
|
7
|
+
include Base
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def allocate_socket
|
12
|
+
@socket = @reactor.rep_socket(self)
|
13
|
+
end
|
14
|
+
end # module REP
|
15
|
+
|
16
|
+
|
17
|
+
module XREP
|
18
|
+
include Base
|
19
|
+
include RoutingEnvelope
|
20
|
+
|
21
|
+
def on_readable socket, messages, envelope
|
22
|
+
@routing = save_routing envelope
|
23
|
+
|
24
|
+
@on_read.call socket, messages, envelope
|
25
|
+
close_messages(envelope + messages)
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def allocate_socket
|
32
|
+
@socket = @reactor.xrep_socket(self)
|
33
|
+
end
|
34
|
+
end # module XREP
|
35
|
+
|
36
|
+
|
37
|
+
module ROUTER
|
38
|
+
include XREP
|
39
|
+
end # module ROUTER
|
40
|
+
|
41
|
+
end # module Server
|
42
|
+
end # ZMQMachine
|
@@ -0,0 +1,41 @@
|
|
1
|
+
|
2
|
+
module ZMQMachine
|
3
|
+
|
4
|
+
module Server
|
5
|
+
|
6
|
+
module REQ
|
7
|
+
include Base
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def allocate_socket
|
12
|
+
@socket = @reactor.req_socket(self)
|
13
|
+
end
|
14
|
+
|
15
|
+
end # module REQ
|
16
|
+
|
17
|
+
module XREQ
|
18
|
+
include Base
|
19
|
+
include RoutingEnvelope
|
20
|
+
|
21
|
+
def on_readable socket, messages, envelope
|
22
|
+
@routing = save_routing envelope
|
23
|
+
|
24
|
+
@on_read.call socket, messages, envelope
|
25
|
+
close_messages(envelope + messages)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def allocate_socket
|
31
|
+
@socket = @reactor.xreq_socket(self)
|
32
|
+
end
|
33
|
+
|
34
|
+
end # module XREQ
|
35
|
+
|
36
|
+
module DEALER
|
37
|
+
include XREQ
|
38
|
+
end # module DEALER
|
39
|
+
|
40
|
+
end # module Server
|
41
|
+
end # ZMQMachine
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
module ZMQMachine
|
3
|
+
|
4
|
+
module Server
|
5
|
+
|
6
|
+
module RoutingEnvelope
|
7
|
+
# Saves the return routing information for XREP sockets
|
8
|
+
def save_routing messages
|
9
|
+
@routing_messages = []
|
10
|
+
@routing_strings = []
|
11
|
+
messages.each do |message|
|
12
|
+
string = message.copy_out_string
|
13
|
+
@routing_strings << string
|
14
|
+
@routing_messages << ZMQ::Message.new(string)
|
15
|
+
end
|
16
|
+
|
17
|
+
@routing_messages
|
18
|
+
end
|
19
|
+
|
20
|
+
def routing_strings
|
21
|
+
@routing_strings.dup
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
|
2
|
+
module ZMQMachine
|
3
|
+
|
4
|
+
module Server
|
5
|
+
|
6
|
+
module SUB
|
7
|
+
include Base
|
8
|
+
|
9
|
+
def initialize configuration
|
10
|
+
@topic = configuration.topic || ''
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
def write messages
|
15
|
+
# no op
|
16
|
+
close messages
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def allocate_socket
|
23
|
+
@socket = @reactor.sub_socket(self)
|
24
|
+
end
|
25
|
+
|
26
|
+
def register_for_events socket
|
27
|
+
subscribe socket, @topic
|
28
|
+
|
29
|
+
super
|
30
|
+
end
|
31
|
+
|
32
|
+
def subscribe socket, topic
|
33
|
+
rc = socket.subscribe topic
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
end # module SUB
|
38
|
+
|
39
|
+
end # module Server
|
40
|
+
end # ZMQMachine
|
data/lib/zm/sockets.rb
CHANGED
data/lib/zm/sockets/base.rb
CHANGED
@@ -129,7 +129,7 @@ module ZMQMachine
|
|
129
129
|
@raw_socket.sendmsgs messages
|
130
130
|
end
|
131
131
|
|
132
|
-
if LibZMQ.version2? || LibZMQ.version3?
|
132
|
+
if ZMQ::LibZMQ.version2? || ZMQ::LibZMQ.version3?
|
133
133
|
|
134
134
|
# Retrieve the IDENTITY value assigned to this socket.
|
135
135
|
#
|
@@ -153,13 +153,13 @@ module ZMQMachine
|
|
153
153
|
rc = @raw_socket.recvmsgs parts, ZMQ::Util.nonblocking_flag
|
154
154
|
|
155
155
|
if ZMQ::Util.resultcode_ok?(rc)
|
156
|
-
|
156
|
+
@handler.on_readable self, parts
|
157
157
|
else
|
158
158
|
# verify errno corresponds to EAGAIN
|
159
159
|
if eagain?
|
160
160
|
more = false
|
161
161
|
elsif valid_socket_error?
|
162
|
-
|
162
|
+
@handler.on_readable_error self, rc
|
163
163
|
end
|
164
164
|
end
|
165
165
|
end
|
@@ -178,15 +178,6 @@ module ZMQMachine
|
|
178
178
|
|
179
179
|
private
|
180
180
|
|
181
|
-
def deliver parts, rc
|
182
|
-
if ZMQ::Util.resultcode_ok?(rc)
|
183
|
-
@handler.on_readable self, parts
|
184
|
-
else
|
185
|
-
# this branch is never called
|
186
|
-
@handler.on_readable_error self, rc
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
181
|
def eagain?
|
191
182
|
ZMQ::EAGAIN == ZMQ::Util.errno
|
192
183
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
|
2
|
+
module ZMQMachine
|
3
|
+
|
4
|
+
module Socket
|
5
|
+
|
6
|
+
# Two socket types (XREQ/XREP also called DEALER/ROUTER) have message
|
7
|
+
# parts for routing the message to the appropriate destination. This
|
8
|
+
# extra routing data is commonly called the routing envelope.
|
9
|
+
#
|
10
|
+
# The module provides logic for separating the routing envelope from
|
11
|
+
# the message body. The envelope is passed separately to the user's
|
12
|
+
# #on_readable method.
|
13
|
+
#
|
14
|
+
module EnvelopeHelp
|
15
|
+
|
16
|
+
# Convenience method for sending a multi-part message. The
|
17
|
+
# +messages+ and +envelope+ arguments must implement Enumerable.
|
18
|
+
#
|
19
|
+
def send_messages messages, envelope = nil
|
20
|
+
envelope ? @raw_socket.sendmsgs(envelope + messages) : @raw_socket.sendmsgs(messages)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Used by the reactor. Never called by user code.
|
24
|
+
#
|
25
|
+
def resume_read
|
26
|
+
rc = 0
|
27
|
+
more = true
|
28
|
+
|
29
|
+
while ZMQ::Util.resultcode_ok?(rc) && more
|
30
|
+
parts, envelope = [], []
|
31
|
+
rc = @raw_socket.recv_multipart parts, envelope, ZMQ::Util.nonblocking_flag
|
32
|
+
|
33
|
+
if ZMQ::Util.resultcode_ok?(rc)
|
34
|
+
@handler.on_readable self, parts, envelope
|
35
|
+
else
|
36
|
+
# verify errno corresponds to EAGAIN
|
37
|
+
if eagain?
|
38
|
+
more = false
|
39
|
+
elsif valid_socket_error?
|
40
|
+
@handler.on_readable_error self, rc
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end # module EnvelopeSeparation
|
47
|
+
|
48
|
+
end # Socket
|
49
|
+
end # ZMQMachine
|
data/lib/zm/sockets/pair.rb
CHANGED
data/lib/zm/sockets/pub.rb
CHANGED
data/lib/zm/sockets/rep.rb
CHANGED
@@ -74,6 +74,51 @@ module ZMQMachine
|
|
74
74
|
end
|
75
75
|
end # class Rep
|
76
76
|
|
77
|
+
class XRep
|
78
|
+
include ZMQMachine::Socket::Base
|
79
|
+
include ZMQMachine::Socket::EnvelopeHelp
|
80
|
+
|
81
|
+
def initialize context, handler
|
82
|
+
@poll_options = ZMQ::POLLIN
|
83
|
+
@kind = :xreply
|
84
|
+
|
85
|
+
super
|
86
|
+
end
|
87
|
+
|
88
|
+
# Attach a handler to the XREP socket.
|
89
|
+
#
|
90
|
+
# A XREP socket has no restrictions on the number of sends and
|
91
|
+
# recieves. Each send will silently prepend a message part to
|
92
|
+
# your outgoing data which the REQ/XREQ socket on the other end
|
93
|
+
# will use for matching up the transaction.
|
94
|
+
#
|
95
|
+
# This socket expects its +handler+ to
|
96
|
+
# implement at least the #on_readable method. This method
|
97
|
+
# will be called whenever a reply arrives. The #on_writable method
|
98
|
+
# will be called continually until the socket HWM is breached.
|
99
|
+
#
|
100
|
+
# For error handling purposes, the handler must also
|
101
|
+
# implement #on_readable_error.
|
102
|
+
#
|
103
|
+
def on_attach handler
|
104
|
+
raise ArgumentError, "Handler must implement an #on_readable method" unless handler.respond_to? :on_readable
|
105
|
+
raise ArgumentError, "Handler must implement an #on_readable_error method" unless handler.respond_to? :on_readable_error
|
106
|
+
raise ArgumentError, "Handler must implement an #on_writable method" unless handler.respond_to? :on_writable
|
107
|
+
raise ArgumentError, "Handler must implement an #on_writable_error method" unless handler.respond_to? :on_writable_error
|
108
|
+
super
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
private
|
113
|
+
|
114
|
+
def allocate_socket context
|
115
|
+
sock = ZMQ::Socket.new context.pointer, ZMQ::XREP
|
116
|
+
sock
|
117
|
+
end
|
118
|
+
end # class XRep
|
119
|
+
|
120
|
+
Router = XRep # same thing, different name
|
121
|
+
|
77
122
|
end # module Socket
|
78
123
|
|
79
124
|
end # module ZMQMachine
|