zmqmachine 0.3.0

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.
@@ -0,0 +1,195 @@
1
+
2
+ require 'rubygems'
3
+ require 'ffi-rzmq'
4
+ require '../lib/zmqmachine'
5
+
6
+
7
+ # Shows how to use a PUB socket to send messages in a fanout
8
+ # manner. A set of SUB sockets subscribe using different topic
9
+ # matches.
10
+ #
11
+ # The example also shows how to communicate between multiple
12
+ # reactors by running some operations in different contexts.
13
+ # Modify which lines are commented in/out within each context
14
+ # to see how performance changes in different scenarios.
15
+ #
16
+
17
+ class PublisherHandler
18
+ attr_reader :sent_count
19
+
20
+ def initialize context, port, topics
21
+ @context = context
22
+ @port = port
23
+ @topics = topics
24
+ @sent_count = 0
25
+ end
26
+
27
+ def on_attach socket
28
+ address = ZM::Address.new '127.0.0.1', @port, :tcp
29
+ rc = socket.bind address
30
+ end
31
+
32
+ def on_writable socket
33
+ topic = @topics[rand(@topics.size)]
34
+ symbol = topic.split('.').first
35
+
36
+ if 'es' == symbol
37
+ payload = "#{topic}|#{rand(1200) + 1}|#{rand(4400)}"
38
+ else
39
+ payload = "#{topic}|#{rand(300) + 1}|#{rand(8000)}"
40
+ end
41
+
42
+ message = ZMQ::Message.new payload
43
+ socket.send_message message
44
+ @sent_count += 1
45
+ end
46
+ end
47
+
48
+ class SubscriberHandler
49
+ attr_reader :received_count, :topics
50
+
51
+ def initialize context, ports, topic = nil, sleep = false
52
+ @context = context
53
+ @received_count = 0
54
+ @ports = ports
55
+ (@topics ||= []) << topic.to_s
56
+ @sleep = sleep
57
+ end
58
+
59
+ def on_attach socket
60
+ @ports.each do |port|
61
+ address = ZM::Address.new '127.0.0.1', port, :tcp
62
+ rc = socket.connect address
63
+
64
+ @topics.each do |topic|
65
+ puts "subscribe to [#{topic}]"
66
+ socket.subscribe topic
67
+ end
68
+ end
69
+ end
70
+
71
+ def on_readable socket, messages
72
+ @received_count += 1
73
+ sleep 0.01 if @sleep
74
+ end
75
+ end
76
+
77
+
78
+ # Mix and match the handlers amongst the 5 reactors below. Make sure that a publisher
79
+ # handler is only getting instantiated and run in one reactor at a time. The subscriber
80
+ # handlers can be instantiated multiple times in each reactor if you so choose.
81
+
82
+ # Run all handlers within the same reactor context
83
+ ctx1 = ZM::Reactor.new(:A).run do |context|
84
+ @pub1_handler = PublisherHandler.new context, 5555, ['futures.us.es.m.10', 'futures.us.es.u.10']
85
+ context.pub_socket @pub1_handler
86
+
87
+ # @pub2_handler = PublisherHandler.new context, 5556, ['futures.us.nq.m.10', 'futures.us.nq.u.10']
88
+ # context.pub_socket @pub2_handler
89
+ #
90
+ # @sub1_handler = SubscriberHandler.new context, [5555, 5556]
91
+ # context.sub_socket @sub1_handler
92
+ #
93
+ # @sub2_handler = SubscriberHandler.new context, [5555], 'futures.us.es.m'
94
+ # context.sub_socket @sub2_handler
95
+ #
96
+ # @sub3_handler = SubscriberHandler.new context, [5555], 'futures.us.es.u'
97
+ # context.sub_socket @sub3_handler
98
+ #
99
+ # @sub4_handler = SubscriberHandler.new context, [5556], 'futures.us.nq.m'
100
+ # context.sub_socket @sub4_handler
101
+ #
102
+ # @sub5_handler = SubscriberHandler.new context, [5555, 5556], 'futures.us.'
103
+ # context.sub_socket @sub5_handler
104
+ end
105
+
106
+ # Or, run each handler in separate contexts each with its
107
+ # own thread.
108
+ ctx2 = ZM::Reactor.new(:B).run do |context|
109
+ # @pub1_handler = PublisherHandler.new context, 5555, ['futures.us.es.m.10', 'futures.us.es.u.10']
110
+ # context.pub_socket @pub1_handler
111
+
112
+ @pub2_handler = PublisherHandler.new context, 5556, ['futures.us.nq.m.10', 'futures.us.nq.u.10']
113
+ context.pub_socket @pub2_handler
114
+
115
+ # @sub1_handler = SubscriberHandler.new context, [5555, 5556]
116
+ # context.sub_socket @sub1_handler
117
+ #
118
+ # @sub2_handler = SubscriberHandler.new context, [5555], 'futures.us.es.m'
119
+ # context.sub_socket @sub2_handler
120
+ #
121
+ # @sub3_handler = SubscriberHandler.new context, [5555], 'futures.us.es.u'
122
+ # context.sub_socket @sub3_handler
123
+ #
124
+ # @sub4_handler = SubscriberHandler.new context, [5556], 'futures.us.nq.m'
125
+ # context.sub_socket @sub4_handler
126
+ #
127
+ # @sub5_handler = SubscriberHandler.new context, [5555, 5556], 'futures.us.'
128
+ # context.sub_socket @sub5_handler
129
+ end
130
+
131
+ ctx3 = ZM::Reactor.new(:C).run do |context|
132
+ # @pub1_handler = PublisherHandler.new context, 5555, ['futures.us.es.m.10', 'futures.us.es.u.10']
133
+ # context.pub_socket @pub1_handler
134
+ #
135
+ # @pub2_handler = PublisherHandler.new context, 5556, ['futures.us.nq.m.10', 'futures.us.nq.u.10']
136
+ # context.pub_socket @pub2_handler
137
+ #
138
+ @sub1_handler = SubscriberHandler.new context, [5555, 5556]
139
+ context.sub_socket @sub1_handler
140
+
141
+ @sub2_handler = SubscriberHandler.new context, [5555], 'futures.us.es.m'
142
+ context.sub_socket @sub2_handler
143
+
144
+ @sub3_handler = SubscriberHandler.new context, [5555], 'futures.us.es.u'
145
+ context.sub_socket @sub3_handler
146
+
147
+ @sub4_handler = SubscriberHandler.new context, [5556], 'futures.us.nq.m'
148
+ context.sub_socket @sub4_handler
149
+
150
+ # @sub5_handler = SubscriberHandler.new context, [5555, 5556], 'futures.us.'
151
+ # context.sub_socket @sub5_handler
152
+ end
153
+
154
+ ctx4 = ZM::Reactor.new(:D).run do |context|
155
+ # @pub1_handler = PublisherHandler.new context, 5555, ['futures.us.es.m.10', 'futures.us.es.u.10']
156
+ # context.pub_socket @pub1_handler
157
+ #
158
+ # @pub2_handler = PublisherHandler.new context, 5556, ['futures.us.nq.m.10', 'futures.us.nq.u.10']
159
+ # context.pub_socket @pub2_handler
160
+ #
161
+ # @sub1_handler = SubscriberHandler.new context, [5555, 5556]
162
+ # context.sub_socket @sub1_handler
163
+ #
164
+ # @sub2_handler = SubscriberHandler.new context, [5555], 'futures.us.es.m'
165
+ # context.sub_socket @sub2_handler
166
+ #
167
+ # @sub3_handler = SubscriberHandler.new context, [5555], 'futures.us.es.u'
168
+ # context.sub_socket @sub3_handler
169
+ #
170
+ # @sub4_handler = SubscriberHandler.new context, [5556], 'futures.us.nq.m'
171
+ # context.sub_socket @sub4_handler
172
+
173
+ @sub5_handler = SubscriberHandler.new context, [5555, 5556], 'futures.us.'
174
+ context.sub_socket @sub5_handler
175
+ end
176
+
177
+ # let's see how many messages we can publish in this many seconds
178
+ sleep_time = 5
179
+ puts "Started at [#{Time.now}]"
180
+ puts "main thread will sleep [#{sleep_time}] seconds before aborting the reactor context threads"
181
+ sleep sleep_time
182
+
183
+ # Exit each reactor after the sleep time
184
+ ctx1.stop
185
+ ctx2.stop
186
+ ctx3.stop
187
+ ctx4.stop
188
+
189
+ puts "sent [#{@pub1_handler.sent_count}]"
190
+ puts "sent [#{@pub2_handler.sent_count}]"
191
+ puts "* [#{@sub1_handler.received_count}]"
192
+ puts "futures.us.ep.m [#{@sub2_handler.received_count}]"
193
+ puts "futures.us.ep.u [#{@sub3_handler.received_count}]"
194
+ puts "futures.us.nq.m [#{@sub4_handler.received_count}]"
195
+ puts "futures.us.nq [#{@sub5_handler.received_count}]"
@@ -0,0 +1,103 @@
1
+
2
+ require 'rubygems'
3
+ require 'ffi-rzmq'
4
+ require '../lib/zmqmachine'
5
+
6
+ # This example illustrates how to write a simple set of
7
+ # handlers for providing message ping-pong using
8
+ # a PAIR socket pair. All activity is asynchronous and
9
+ # relies on non-blocking I/O.
10
+ #
11
+ # The throttling aspect doesn't really kick in; need to
12
+ # ask the 0mq guys for clarity.
13
+
14
+ class PongHandler
15
+ attr_reader :sent_count, :received_count
16
+
17
+ def initialize context
18
+ @context = context
19
+ @sent_count = 0
20
+ @received_count = 0
21
+ end
22
+
23
+ def on_attach socket
24
+ address = ZM::Address.new '127.0.0.1', 5555, :tcp
25
+ rc = socket.bind address
26
+ end
27
+
28
+ def on_readable socket, messages
29
+ @received_count += 1
30
+ pong socket, messages.first
31
+ end
32
+
33
+ def on_writable socket
34
+ #puts "pong on_writable"
35
+ end
36
+
37
+ def pong socket, message
38
+ socket.send_message message
39
+ @sent_count += 1
40
+ end
41
+ end
42
+
43
+ class PingHandler
44
+ attr_reader :sent_count, :received_count
45
+
46
+ def initialize context
47
+ @context = context
48
+ @sent_count = 0
49
+ @received_count = 0
50
+ end
51
+
52
+ def on_attach socket
53
+ address = ZM::Address.new '127.0.0.1', 5555, :tcp
54
+ rc = socket.connect address
55
+ end
56
+
57
+ def on_readable socket, messages
58
+ @received_count += 1
59
+ end
60
+
61
+ def on_writable socket
62
+ #puts "ping on_writable"
63
+ ping socket
64
+ end
65
+
66
+ # send as fast as possible until we hit our high water
67
+ # mark and get EAGAIN; then break
68
+ def ping socket
69
+ message = ZMQ::Message.new "#{'b' * 2048}"
70
+ rc = socket.send_message message
71
+ @sent_count += 1
72
+ end
73
+ end
74
+
75
+
76
+
77
+ # Run both handlers within the same reactor context
78
+ ctx1 = ZM::Reactor.new(:pong).run do |context|
79
+ @pong_handler = PongHandler.new context
80
+ context.pair_socket @pong_handler
81
+
82
+ # If you uncomment these 2 lines, comment out the
83
+ # +ctx2+ block below.
84
+ # @ping_handler = PingHandler.new context
85
+ # context.pair_socket @ping_handler
86
+ end
87
+
88
+ # Or, run each handler in separate contexts each with its
89
+ # own thread.
90
+ ctx2 = ZM::Reactor.new(:ping).run do |context|
91
+ @ping_handler = PingHandler.new context
92
+ context.pair_socket @ping_handler
93
+ end
94
+
95
+ # let's see how many messages we can transfer in this many seconds
96
+ sleep_time = 5
97
+ puts "Started at [#{Time.now}]"
98
+ puts "main thread will sleep [#{sleep_time}] seconds before aborting the context threads"
99
+ sleep sleep_time
100
+
101
+ ctx1.stop
102
+ ctx2.stop
103
+ puts "received [#{@pong_handler.received_count}], sent [#{@ping_handler.sent_count}]"
data/lib/zm/address.rb ADDED
@@ -0,0 +1,70 @@
1
+ #--
2
+ #
3
+ # Author:: Chuck Remes
4
+ # Homepage:: http://github.com/chuckremes/zmqmachine
5
+ # Date:: 20100602
6
+ #
7
+ #----------------------------------------------------------------------------
8
+ #
9
+ # Copyright (C) 2010 by Chuck Remes. All Rights Reserved.
10
+ # Email: cremes at mac dot com
11
+ #
12
+ # (The MIT License)
13
+ #
14
+ # Permission is hereby granted, free of charge, to any person obtaining
15
+ # a copy of this software and associated documentation files (the
16
+ # 'Software'), to deal in the Software without restriction, including
17
+ # without limitation the rights to use, copy, modify, merge, publish,
18
+ # distribute, sublicense, and/or sell copies of the Software, and to
19
+ # permit persons to whom the Software is furnished to do so, subject to
20
+ # the following conditions:
21
+ #
22
+ # The above copyright notice and this permission notice shall be
23
+ # included in all copies or substantial portions of the Software.
24
+ #
25
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
26
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
28
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
29
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
30
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
31
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32
+ #
33
+ #---------------------------------------------------------------------------
34
+ #
35
+ #
36
+
37
+ module ZMQMachine
38
+
39
+ #FIXME: needs to handle ipc and inproc transports better, e.g.
40
+ # there is no port component to either one.
41
+ #
42
+ class Address
43
+ attr_reader :host, :port, :transport
44
+
45
+ # +type+ : :tcp, :pgm or :inprocess
46
+ def initialize host, port, type = :tcp
47
+ @host = host
48
+ @port = port
49
+ @transport = determine_type type
50
+ end
51
+
52
+ def to_s
53
+ "#{@transport}://#{@host}:#{@port}"
54
+ end
55
+
56
+ private
57
+
58
+ def determine_type type
59
+ case type
60
+ when :inprocess
61
+ :inproc
62
+ when :tcp, :pgm
63
+ type
64
+ else
65
+ raise UnknownAddressError, "Unknown address transport type [#{type}]; must be :tcp, :pgm, or :inprocess"
66
+ end
67
+ end
68
+
69
+ end # class Address
70
+ end # module ZMQMachine
@@ -0,0 +1,209 @@
1
+ #--
2
+ #
3
+ # Author:: Francis Cianfrocca (gmail: blackhedd)
4
+ # Homepage:: http://rubyeventmachine.com
5
+ # Date:: 16 Jul 2006
6
+ #
7
+ # See EventMachine and EventMachine::Connection for documentation and
8
+ # usage examples.
9
+ #
10
+ #----------------------------------------------------------------------------
11
+ #
12
+ # Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
13
+ # Gmail: blackhedd
14
+ #
15
+ # This program is free software; you can redistribute it and/or modify
16
+ # it under the terms of either: 1) the GNU General Public License
17
+ # as published by the Free Software Foundation; either version 2 of the
18
+ # License, or (at your option) any later version; or 2) Ruby's License.
19
+ #
20
+ #---------------------------------------------------------------------------
21
+ #
22
+ #
23
+
24
+ module ZMQMachine
25
+
26
+ module Deferrable
27
+
28
+ # Specify a block to be executed if and when the Deferrable object receives
29
+ # a status of :succeeded. See #set_deferred_status for more information.
30
+ #
31
+ # Calling this method on a Deferrable object whose status is not yet known
32
+ # will cause the callback block to be stored on an internal list.
33
+ # If you call this method on a Deferrable whose status is :succeeded, the
34
+ # block will be executed immediately, receiving the parameters given to the
35
+ # prior #set_deferred_status call.
36
+ #
37
+ #--
38
+ # If there is no status, add a callback to an internal list.
39
+ # If status is succeeded, execute the callback immediately.
40
+ # If status is failed, do nothing.
41
+ #
42
+ def callback &block
43
+ return unless block
44
+ @deferred_status ||= :unknown
45
+ if @deferred_status == :succeeded
46
+ block.call(*@deferred_args)
47
+ elsif @deferred_status != :failed
48
+ @callbacks ||= []
49
+ @callbacks.unshift block
50
+ end
51
+ end
52
+
53
+ # Cancels an outstanding callback to &block if any. Undoes the action of #callback.
54
+ #
55
+ def cancel_callback block
56
+ @callbacks ||= []
57
+ @callbacks.delete block
58
+ end
59
+
60
+ # Specify a block to be executed if and when the Deferrable object receives
61
+ # a status of :failed. See #set_deferred_status for more information.
62
+ #--
63
+ # If there is no status, add an errback to an internal list.
64
+ # If status is failed, execute the errback immediately.
65
+ # If status is succeeded, do nothing.
66
+ #
67
+ def errback &block
68
+ return unless block
69
+ @deferred_status ||= :unknown
70
+ if @deferred_status == :failed
71
+ block.call(*@deferred_args)
72
+ elsif @deferred_status != :succeeded
73
+ @errbacks ||= []
74
+ @errbacks.unshift block # << block
75
+ end
76
+ end
77
+
78
+ # Cancels an outstanding errback to &block if any. Undoes the action of #errback.
79
+ #
80
+ def cancel_errback block
81
+ @errbacks ||= []
82
+ @errbacks.delete block
83
+ end
84
+
85
+ # Sets the "disposition" (status) of the Deferrable object. See also the large set of
86
+ # sugarings for this method.
87
+ # Note that if you call this method without arguments,
88
+ # no arguments will be passed to the callback/errback.
89
+ # If the user has coded these with arguments, then the
90
+ # user code will throw an argument exception.
91
+ # Implementors of deferrable classes <b>must</b>
92
+ # document the arguments they will supply to user callbacks.
93
+ #
94
+ # OBSERVE SOMETHING VERY SPECIAL here: you may call this method even
95
+ # on the INSIDE of a callback. This is very useful when a previously-registered
96
+ # callback wants to change the parameters that will be passed to subsequently-registered
97
+ # ones.
98
+ #
99
+ # You may give either :succeeded or :failed as the status argument.
100
+ #
101
+ # If you pass :succeeded, then all of the blocks passed to the object using the #callback
102
+ # method (if any) will be executed BEFORE the #set_deferred_status method returns. All of the blocks
103
+ # passed to the object using #errback will be discarded.
104
+ #
105
+ # If you pass :failed, then all of the blocks passed to the object using the #errback
106
+ # method (if any) will be executed BEFORE the #set_deferred_status method returns. All of the blocks
107
+ # passed to the object using # callback will be discarded.
108
+ #
109
+ # If you pass any arguments to #set_deferred_status in addition to the status argument,
110
+ # they will be passed as arguments to any callbacks or errbacks that are executed.
111
+ # It's your responsibility to ensure that the argument lists specified in your callbacks and
112
+ # errbacks match the arguments given in calls to #set_deferred_status, otherwise Ruby will raise
113
+ # an ArgumentError.
114
+ #
115
+ #--
116
+ # We're shifting callbacks off and discarding them as we execute them.
117
+ # This is valid because by definition callbacks are executed no more than
118
+ # once. It also has the magic effect of permitting recursive calls, which
119
+ # means that a callback can call #set_deferred_status and change the parameters
120
+ # that will be sent to subsequent callbacks down the chain.
121
+ #
122
+ # Changed @callbacks and @errbacks from push/shift to unshift/pop, per suggestion
123
+ # by Kirk Haines, to work around the memory leak bug that still exists in many Ruby
124
+ # versions.
125
+ #
126
+ # Changed 15Sep07: after processing callbacks or errbacks, CLEAR the other set of
127
+ # handlers. This gets us a little closer to the behavior of Twisted's "deferred,"
128
+ # which only allows status to be set once. Prior to making this change, it was possible
129
+ # to "succeed" a Deferrable (triggering its callbacks), and then immediately "fail" it,
130
+ # triggering its errbacks! That is clearly undesirable, but it's just as undesirable
131
+ # to raise an exception is status is set more than once on a Deferrable. The latter
132
+ # behavior would invalidate the idiom of resetting arguments by setting status from
133
+ # within a callback or errback, but more seriously it would cause spurious errors
134
+ # if a Deferrable was timed out and then an attempt was made to succeed it. See the
135
+ # comments under the new method #timeout.
136
+ #
137
+ def set_deferred_status status, *args
138
+ cancel_timeout
139
+ @errbacks ||= nil
140
+ @callbacks ||= nil
141
+ @deferred_status = status
142
+ @deferred_args = args
143
+ case @deferred_status
144
+ when :succeeded
145
+ if @callbacks
146
+ while cb = @callbacks.pop
147
+ cb.call(*@deferred_args)
148
+ end
149
+ end
150
+ @errbacks.clear if @errbacks
151
+ when :failed
152
+ if @errbacks
153
+ while eb = @errbacks.pop
154
+ eb.call(*@deferred_args)
155
+ end
156
+ end
157
+ @callbacks.clear if @callbacks
158
+ end
159
+ end
160
+
161
+
162
+ # Setting a timeout on a Deferrable causes it to go into the failed state after
163
+ # the Timeout expires (passing no arguments to the object's errbacks).
164
+ # Setting the status at any time prior to a call to the expiration of the timeout
165
+ # will cause the timer to be cancelled.
166
+ def timeout seconds, *args
167
+ cancel_timeout
168
+ me = self
169
+
170
+ # we use milliseconds, not seconds, so adjust the passed in time
171
+ seconds *= 1000
172
+ @deferred_timeout = ZMQMachine::Timers.add_oneshot seconds {me.fail(*args)}
173
+ end
174
+
175
+ # Cancels an outstanding timeout if any. Undoes the action of #timeout.
176
+ #
177
+ def cancel_timeout
178
+ @deferred_timeout ||= nil
179
+ if @deferred_timeout
180
+ @deferred_timeout.cancel
181
+ @deferred_timeout = nil
182
+ end
183
+ end
184
+
185
+
186
+ # Sugar for set_deferred_status(:succeeded, ...)
187
+ #
188
+ def succeed *args
189
+ set_deferred_status :succeeded, *args
190
+ end
191
+ alias set_deferred_success succeed
192
+
193
+ # Sugar for set_deferred_status(:failed, ...)
194
+ #
195
+ def fail *args
196
+ set_deferred_status :failed, *args
197
+ end
198
+ alias set_deferred_failure fail
199
+ end
200
+
201
+
202
+ # DefaultDeferrable is an otherwise empty class that includes Deferrable.
203
+ # This is very useful when you just need to return a Deferrable object
204
+ # as a way of communicating deferred status to some other part of a program.
205
+ class DefaultDeferrable
206
+ include Deferrable
207
+ end
208
+
209
+ end # module ZMQMachine
@@ -0,0 +1,45 @@
1
+ #--
2
+ #
3
+ # Author:: Chuck Remes
4
+ # Homepage:: http://github.com/chuckremes/zmqmachine
5
+ # Date:: 20100602
6
+ #
7
+ #----------------------------------------------------------------------------
8
+ #
9
+ # Copyright (C) 2010 by Chuck Remes. All Rights Reserved.
10
+ # Email: cremes at mac dot com
11
+ #
12
+ # (The MIT License)
13
+ #
14
+ # Permission is hereby granted, free of charge, to any person obtaining
15
+ # a copy of this software and associated documentation files (the
16
+ # 'Software'), to deal in the Software without restriction, including
17
+ # without limitation the rights to use, copy, modify, merge, publish,
18
+ # distribute, sublicense, and/or sell copies of the Software, and to
19
+ # permit persons to whom the Software is furnished to do so, subject to
20
+ # the following conditions:
21
+ #
22
+ # The above copyright notice and this permission notice shall be
23
+ # included in all copies or substantial portions of the Software.
24
+ #
25
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
26
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
28
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
29
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
30
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
31
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32
+ #
33
+ #---------------------------------------------------------------------------
34
+ #
35
+ #
36
+
37
+ module ZMQMachine
38
+
39
+ class TimeoutError < StandardError; end
40
+
41
+ class UnknownAddressError < StandardError; end
42
+
43
+ class NotReadyError < StandardError; end
44
+
45
+ end # module ZMQMachine
data/lib/zm/message.rb ADDED
@@ -0,0 +1,52 @@
1
+ #--
2
+ #
3
+ # Author:: Chuck Remes
4
+ # Homepage:: http://github.com/chuckremes/zmqmachine
5
+ # Date:: 20100602
6
+ #
7
+ #----------------------------------------------------------------------------
8
+ #
9
+ # Copyright (C) 2010 by Chuck Remes. All Rights Reserved.
10
+ # Email: cremes at mac dot com
11
+ #
12
+ # (The MIT License)
13
+ #
14
+ # Permission is hereby granted, free of charge, to any person obtaining
15
+ # a copy of this software and associated documentation files (the
16
+ # 'Software'), to deal in the Software without restriction, including
17
+ # without limitation the rights to use, copy, modify, merge, publish,
18
+ # distribute, sublicense, and/or sell copies of the Software, and to
19
+ # permit persons to whom the Software is furnished to do so, subject to
20
+ # the following conditions:
21
+ #
22
+ # The above copyright notice and this permission notice shall be
23
+ # included in all copies or substantial portions of the Software.
24
+ #
25
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
26
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
28
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
29
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
30
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
31
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32
+ #
33
+ #---------------------------------------------------------------------------
34
+ #
35
+ #
36
+
37
+ module ZMQMachine
38
+
39
+ module Message
40
+
41
+ # A unique identifier for this message
42
+ def identity
43
+
44
+ end
45
+
46
+ def encode
47
+ raise NotImplementedError, "You must implement the #encode method in your Message class", caller
48
+ # FIXME: default to json encoding?
49
+ end
50
+
51
+ end # module Message
52
+ end # module ZMQMachine