zmqmachine 0.6.0 → 0.7.1

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 (44) hide show
  1. data/.gitignore +15 -0
  2. data/AUTHORS.txt +3 -0
  3. data/History.txt +19 -0
  4. data/examples/fake_ftp.rb +9 -1
  5. data/examples/one_handed_ping_pong.rb +2 -1
  6. data/examples/ping_pong.rb +2 -2
  7. data/examples/pub_sub.rb +10 -4
  8. data/examples/pubsub_forwarder.rb +8 -3
  9. data/examples/throttled_ping_pong.rb +2 -2
  10. data/lib/zm/configuration.rb +129 -0
  11. data/lib/zm/device.rb +4 -0
  12. data/lib/zm/device/configuration.rb +24 -0
  13. data/lib/zm/{devices → device}/forwarder.rb +48 -46
  14. data/lib/zm/{devices → device}/queue.rb +63 -44
  15. data/lib/zm/log_client.rb +2 -2
  16. data/lib/zm/log_server.rb +68 -0
  17. data/lib/zm/reactor.rb +42 -29
  18. data/lib/zm/server.rb +4 -0
  19. data/lib/zm/server/base.rb +139 -0
  20. data/lib/zm/server/configuration.rb +53 -0
  21. data/lib/zm/server/pair.rb +23 -0
  22. data/lib/zm/server/pub.rb +23 -0
  23. data/lib/zm/server/pull.rb +24 -0
  24. data/lib/zm/server/push.rb +23 -0
  25. data/lib/zm/server/rep.rb +42 -0
  26. data/lib/zm/server/req.rb +41 -0
  27. data/lib/zm/server/routing_envelope.rb +26 -0
  28. data/lib/zm/server/sub.rb +40 -0
  29. data/lib/zm/sockets.rb +1 -1
  30. data/lib/zm/sockets/base.rb +3 -12
  31. data/lib/zm/sockets/envelope_help.rb +49 -0
  32. data/lib/zm/sockets/pair.rb +0 -1
  33. data/lib/zm/sockets/pub.rb +0 -1
  34. data/lib/zm/sockets/rep.rb +45 -0
  35. data/lib/zm/sockets/req.rb +46 -1
  36. data/lib/zm/sockets/sub.rb +0 -1
  37. data/lib/zm/timers.rb +26 -13
  38. data/lib/zmqmachine.rb +1 -1
  39. data/version.txt +1 -1
  40. data/zmqmachine.gemspec +6 -6
  41. metadata +90 -91
  42. data/lib/zm/devices.rb +0 -4
  43. data/lib/zm/sockets/xrep.rb +0 -86
  44. 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
@@ -1,4 +1,4 @@
1
1
 
2
- %w( base req rep pair pub sub xreq xrep push pull ).each do |rb_file|
2
+ %w( base envelope_help req rep pair pub sub push pull ).each do |rb_file|
3
3
  require File.join(File.dirname(__FILE__), 'sockets', rb_file)
4
4
  end
@@ -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
- deliver(parts, rc)
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
- deliver([], rc)
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
@@ -46,7 +46,6 @@ module ZMQMachine
46
46
  @kind = :pair
47
47
 
48
48
  super
49
- @state = :ready
50
49
  end
51
50
 
52
51
  # Attach a handler to the PAIR socket.
@@ -46,7 +46,6 @@ module ZMQMachine
46
46
  @kind = :pub
47
47
 
48
48
  super
49
- @state = :ready
50
49
  end
51
50
 
52
51
  # Attach a handler to the PUB socket.
@@ -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