zmqmachine 0.3.2 → 0.4.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.
- data/History.txt +16 -0
- data/README.rdoc +8 -6
- data/Rakefile +1 -1
- data/examples/pubsub_forwarder.rb +0 -15
- data/lib/zm/devices/forwarder.rb +6 -6
- data/lib/zm/devices/queue.rb +8 -7
- data/lib/zm/reactor.rb +31 -11
- data/lib/zm/sockets/base.rb +21 -13
- data/lib/zm/timers.rb +90 -27
- data/version.txt +1 -1
- data/zmqmachine.gemspec +9 -9
- metadata +89 -85
data/History.txt
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
== 0.4.0 / 2010-12-16
|
2
|
+
* Replaced SortedSet in Timers with an Array and a custom routine
|
3
|
+
for finding the in-order index for an insert. The routine
|
4
|
+
uses a binary search algo so it can find the proper index in
|
5
|
+
O(nlog n) time. This resulted in a 2 order of magnitude perf
|
6
|
+
increase when using more than a handful of timers.
|
7
|
+
* Modified the default reactor poll interval to 10ms from 100usec.
|
8
|
+
Also, fixed the poll routine so that it sleeps for poll_interval
|
9
|
+
when there are no procs scheduled and there are no sockets
|
10
|
+
registered. With no sockets, the call to Poller#poll returns
|
11
|
+
immediately. This was showing as a busy loop and pushing CPU
|
12
|
+
to 100% for some users.
|
13
|
+
With this change, timers now have a minimum *default* resolution
|
14
|
+
of 10 milliseconds. The poll interval can be overridden and set to
|
15
|
+
a minimum of 1ms for better timing controls.
|
16
|
+
|
1
17
|
== 0.3.2 / 2010-08-25
|
2
18
|
* Fixed a bug in Timers where the timers were never getting removed
|
3
19
|
after they fired. Bug was caused by a Ruby bug with #delete_if. While
|
data/README.rdoc
CHANGED
@@ -20,7 +20,7 @@ descriptors. This isn't on my roadmap but patches are accepted.
|
|
20
20
|
|
21
21
|
== FEATURES/PROBLEMS:
|
22
22
|
|
23
|
-
*
|
23
|
+
* Very few specs.
|
24
24
|
|
25
25
|
* Documentation is limited. I need to write up a lot more detail on the Handler classes passed
|
26
26
|
to socket instances and how this differs from the Eventmachine way.
|
@@ -41,18 +41,20 @@ Read and execute the examples in the examples directory.
|
|
41
41
|
|
42
42
|
Requires the 0mq library
|
43
43
|
|
44
|
-
* 0mq 2.0.
|
44
|
+
* 0mq 2.0.10 or 2.1 and later
|
45
45
|
|
46
46
|
Depends on 2 external gems.
|
47
47
|
|
48
|
-
* ffi-rzmq (>= 0.
|
49
|
-
* ffi (
|
48
|
+
* ffi-rzmq (>= 0.7.0)
|
49
|
+
* ffi (>= 1.0.0)
|
50
50
|
|
51
51
|
== INSTALL:
|
52
52
|
|
53
53
|
Make sure the 0MQ library is already installed on your system. Secondly,
|
54
|
-
|
55
|
-
|
54
|
+
verify the ffi-rzmq gem is installed (available from rubygems.org).
|
55
|
+
|
56
|
+
Lastly, install the zmqmachine gem from rubygems.org. Alternately, build
|
57
|
+
and install directly from a cloned git repository.
|
56
58
|
|
57
59
|
% git clone github.com/chuckremes/zmqmachine.git
|
58
60
|
% cd zmqmachine
|
data/Rakefile
CHANGED
@@ -21,11 +21,9 @@ class PublisherHandler
|
|
21
21
|
def on_attach socket
|
22
22
|
address = ZM::Address.new '127.0.0.1', @port, :tcp
|
23
23
|
rc = socket.connect address
|
24
|
-
# puts "publisher on_attach rc [#{rc}]"
|
25
24
|
end
|
26
25
|
|
27
26
|
def on_writable socket
|
28
|
-
# puts "publisher writing..."
|
29
27
|
topic = @topics[rand(@topics.size)]
|
30
28
|
symbol = topic.split('.').first
|
31
29
|
|
@@ -56,7 +54,6 @@ class SubscriberHandler
|
|
56
54
|
@ports.each do |port|
|
57
55
|
address = ZM::Address.new '127.0.0.1', port, :tcp
|
58
56
|
rc = socket.connect address
|
59
|
-
# puts "subscriber on_attach rc [#{rc}]"
|
60
57
|
|
61
58
|
@topics.each do |topic|
|
62
59
|
puts "subscribe to [#{topic}]"
|
@@ -83,12 +80,6 @@ ctx1 = ZM::Reactor.new(:A).run do |context|
|
|
83
80
|
|
84
81
|
forwarder = ZM::Device::Forwarder.new context, incoming, outgoing
|
85
82
|
puts "forwarder started"
|
86
|
-
|
87
|
-
# context.oneshot_timer(3000) do
|
88
|
-
# puts "reactor one shutting down..."
|
89
|
-
# context.stop
|
90
|
-
# puts "reactor one shut down"
|
91
|
-
# end
|
92
83
|
end
|
93
84
|
|
94
85
|
# Or, run each handler in separate contexts each with its
|
@@ -118,12 +109,6 @@ ctx2 = ZM::Reactor.new(:B).run do |context|
|
|
118
109
|
@sub5_handler = SubscriberHandler.new context, [5556], 'futures.us.'
|
119
110
|
context.sub_socket @sub5_handler
|
120
111
|
end
|
121
|
-
|
122
|
-
# context.oneshot_timer(sleep_time * 1000) do
|
123
|
-
# puts "reactor two shutting down..."
|
124
|
-
# context.stop
|
125
|
-
# puts "reactor two shut down"
|
126
|
-
# end
|
127
112
|
end
|
128
113
|
|
129
114
|
# let's see how many messages we can publish in this many seconds
|
data/lib/zm/devices/forwarder.rb
CHANGED
@@ -65,10 +65,10 @@ module ZMQMachine
|
|
65
65
|
class Handler
|
66
66
|
attr_accessor :socket_out
|
67
67
|
|
68
|
-
def initialize reactor, address,
|
68
|
+
def initialize reactor, address, verbose = false
|
69
69
|
@reactor = reactor
|
70
70
|
@address = address
|
71
|
-
@
|
71
|
+
@verbose = verbose
|
72
72
|
end
|
73
73
|
|
74
74
|
def on_attach socket
|
@@ -84,7 +84,7 @@ module ZMQMachine
|
|
84
84
|
end
|
85
85
|
|
86
86
|
def on_readable socket, messages
|
87
|
-
messages.each { |msg|
|
87
|
+
messages.each { |msg| puts "[fwd] [#{msg.copy_out_string}]" } if @verbose
|
88
88
|
|
89
89
|
socket_out.send_messages messages if @socket_out
|
90
90
|
end
|
@@ -96,13 +96,13 @@ module ZMQMachine
|
|
96
96
|
#
|
97
97
|
# Forwards all messages received by the +incoming+ address to the +outgoing+ address.
|
98
98
|
#
|
99
|
-
def initialize reactor, incoming, outgoing,
|
99
|
+
def initialize reactor, incoming, outgoing, verbose = false
|
100
100
|
incoming = Address.from_string incoming if incoming.kind_of? String
|
101
101
|
outgoing = Address.from_string outgoing if outgoing.kind_of? String
|
102
102
|
|
103
103
|
# setup the handlers for processing messages
|
104
|
-
@handler_in = Handler.new reactor, incoming,
|
105
|
-
@handler_out = Handler.new reactor, outgoing,
|
104
|
+
@handler_in = Handler.new reactor, incoming, verbose
|
105
|
+
@handler_out = Handler.new reactor, outgoing, verbose
|
106
106
|
|
107
107
|
# create each socket and pass in the appropriate handler
|
108
108
|
@incoming = reactor.sub_socket @handler_in
|
data/lib/zm/devices/queue.rb
CHANGED
@@ -67,10 +67,10 @@ module ZMQMachine
|
|
67
67
|
class Handler
|
68
68
|
attr_accessor :socket_out
|
69
69
|
|
70
|
-
def initialize reactor, address,
|
70
|
+
def initialize reactor, address, verbose = false, dir = 0
|
71
71
|
@reactor = reactor
|
72
72
|
@address = address
|
73
|
-
@
|
73
|
+
@verbose = verbose
|
74
74
|
@dir = dir
|
75
75
|
end
|
76
76
|
|
@@ -85,10 +85,11 @@ module ZMQMachine
|
|
85
85
|
end
|
86
86
|
|
87
87
|
def on_readable socket, messages
|
88
|
-
messages.each { |msg| puts "[#{@dir}] [#{msg.copy_out_string}]" } if @
|
88
|
+
messages.each { |msg| puts "[Q#{@dir}] [#{msg.copy_out_string}]" } if @verbose
|
89
89
|
|
90
90
|
if @socket_out
|
91
|
-
|
91
|
+
# FIXME: need to be able to handle EAGAIN/failed send
|
92
|
+
rc = socket_out.send_messages messages
|
92
93
|
end
|
93
94
|
end
|
94
95
|
end # class Handler
|
@@ -99,13 +100,13 @@ module ZMQMachine
|
|
99
100
|
#
|
100
101
|
# Routes all messages received by either address to the other address.
|
101
102
|
#
|
102
|
-
def initialize reactor, incoming, outgoing,
|
103
|
+
def initialize reactor, incoming, outgoing, verbose = false
|
103
104
|
incoming = Address.from_string incoming if incoming.kind_of? String
|
104
105
|
outgoing = Address.from_string outgoing if outgoing.kind_of? String
|
105
106
|
|
106
107
|
# setup the handlers for processing messages
|
107
|
-
@handler_in = Handler.new reactor, incoming,
|
108
|
-
@handler_out = Handler.new reactor, outgoing,
|
108
|
+
@handler_in = Handler.new reactor, incoming, verbose, :in
|
109
|
+
@handler_out = Handler.new reactor, outgoing, verbose, :out
|
109
110
|
|
110
111
|
# create each socket and pass in the appropriate handler
|
111
112
|
@incoming = reactor.xrep_socket @handler_in
|
data/lib/zm/reactor.rb
CHANGED
@@ -40,9 +40,9 @@ module ZMQMachine
|
|
40
40
|
attr_reader :name
|
41
41
|
|
42
42
|
# +poll_interval+ is the number of milliseconds to block while
|
43
|
-
# waiting for new 0mq socket events; default is
|
43
|
+
# waiting for new 0mq socket events; default is 10
|
44
44
|
#
|
45
|
-
def initialize name, poll_interval =
|
45
|
+
def initialize name, poll_interval = 10
|
46
46
|
@name = name
|
47
47
|
@running = false
|
48
48
|
@thread = nil
|
@@ -80,7 +80,7 @@ module ZMQMachine
|
|
80
80
|
@thread = Thread.new do
|
81
81
|
blk.call self if blk
|
82
82
|
|
83
|
-
while !@stopping &&
|
83
|
+
while !@stopping && running? do
|
84
84
|
run_once
|
85
85
|
end
|
86
86
|
|
@@ -114,7 +114,7 @@ module ZMQMachine
|
|
114
114
|
def join delay = nil
|
115
115
|
# don't allow the thread to try and join itself and only worry about
|
116
116
|
# joining for live threads
|
117
|
-
if @thread.alive? && @thread != Thread.current
|
117
|
+
if running? && @thread.alive? && @thread != Thread.current
|
118
118
|
if delay
|
119
119
|
# convert to seconds to meet the argument expectations of Thread#join
|
120
120
|
seconds = delay / 1000.0
|
@@ -131,9 +131,11 @@ module ZMQMachine
|
|
131
131
|
# and kill any pending I/O.
|
132
132
|
#
|
133
133
|
def kill
|
134
|
-
|
135
|
-
|
136
|
-
|
134
|
+
if running?
|
135
|
+
@stopping = true
|
136
|
+
@thread.kill
|
137
|
+
cleanup
|
138
|
+
end
|
137
139
|
end
|
138
140
|
|
139
141
|
# Schedules a proc or block to execute on the next trip through the
|
@@ -342,6 +344,13 @@ module ZMQMachine
|
|
342
344
|
@timers.reschedule
|
343
345
|
end
|
344
346
|
|
347
|
+
def list_timers
|
348
|
+
@timers.list.each do |timer|
|
349
|
+
name = timer.respond_to?(:name) ? timer.timer_proc.name : timer.timer_proc.to_s
|
350
|
+
puts "fire time [#{Time.at(timer.fire_time / 1000)}], method [#{name}]"
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
345
354
|
|
346
355
|
private
|
347
356
|
|
@@ -379,7 +388,16 @@ module ZMQMachine
|
|
379
388
|
end
|
380
389
|
|
381
390
|
def poll
|
382
|
-
@
|
391
|
+
if (@proc_queue.empty? && @sockets.empty?) || @poller.size.zero?
|
392
|
+
# when there are no sockets registered, @poller.poll would return immediately;
|
393
|
+
# the same is true when sockets are registered but *not* for any events;
|
394
|
+
# doing so spikes the CPU even though there is no work to do
|
395
|
+
# take a short nap here (10ms by default) unless there are procs scheduled
|
396
|
+
# to run (e.g. via next_tick)
|
397
|
+
sleep(@poll_interval / 1000)
|
398
|
+
else
|
399
|
+
@poller.poll @poll_interval
|
400
|
+
end
|
383
401
|
|
384
402
|
@poller.readables.each { |sock| @raw_to_socket[sock].resume_read }
|
385
403
|
@poller.writables.each { |sock| @raw_to_socket[sock].resume_write }
|
@@ -398,10 +416,12 @@ module ZMQMachine
|
|
398
416
|
end
|
399
417
|
|
400
418
|
|
401
|
-
#
|
419
|
+
# Unnecessary to convert the number to microseconds; the ffi-rzmq
|
420
|
+
# library does this for us.
|
421
|
+
#
|
402
422
|
def determine_interval interval
|
403
|
-
# set a lower bound of
|
404
|
-
interval <= 0 ?
|
423
|
+
# set a lower bound of 1000 usec so we don't burn up the CPU
|
424
|
+
interval <= 0 ? 1.0 : interval.to_i
|
405
425
|
end
|
406
426
|
|
407
427
|
end # class Reactor
|
data/lib/zm/sockets/base.rb
CHANGED
@@ -134,6 +134,9 @@ module ZMQMachine
|
|
134
134
|
rc = send_message messages.at(i), true
|
135
135
|
i += 1
|
136
136
|
end
|
137
|
+
|
138
|
+
# FIXME: bug; if any of the message parts fail (rc != 0) we don't see that here; the
|
139
|
+
# #send_message function should capture exceptions and turn them into integers for bubbling
|
137
140
|
|
138
141
|
# send the last message without the multipart arg to flush
|
139
142
|
# the message to the 0mq queue
|
@@ -157,21 +160,26 @@ module ZMQMachine
|
|
157
160
|
# was successfully dequeued. The use of rc here is really ugly and wrong.
|
158
161
|
#
|
159
162
|
def resume_read
|
160
|
-
|
161
|
-
|
162
|
-
#
|
163
|
-
|
164
|
-
|
165
|
-
#puts "get next part"
|
163
|
+
rc = 0
|
164
|
+
|
165
|
+
# loop and deliver all messages until the socket returns EAGAIN
|
166
|
+
while 0 == rc
|
167
|
+
messages = []
|
166
168
|
rc = read_message_part messages
|
167
|
-
#puts "resume_read:
|
169
|
+
#puts "resume_read: rc1 [#{rc}], more_parts? [#{@raw_socket.more_parts?}]"
|
170
|
+
|
171
|
+
while 0 == rc && @raw_socket.more_parts?
|
172
|
+
#puts "get next part"
|
173
|
+
rc = read_message_part messages
|
174
|
+
#puts "resume_read: rc2 [#{rc}]"
|
175
|
+
end
|
176
|
+
#puts "no more parts, ready to deliver"
|
177
|
+
|
178
|
+
# only deliver the messages when rc is 0; otherwise, we
|
179
|
+
# may have gotten EAGAIN and no message was read;
|
180
|
+
# don't deliver empty messages
|
181
|
+
deliver messages, rc if 0 == rc
|
168
182
|
end
|
169
|
-
#puts "no more parts, ready to deliver"
|
170
|
-
|
171
|
-
# only deliver the messages when rc is 0; otherwise, we
|
172
|
-
# may have gotten EAGAIN and no message was read;
|
173
|
-
# don't deliver empty messages
|
174
|
-
deliver messages, rc if 0 == rc
|
175
183
|
end
|
176
184
|
|
177
185
|
# Used by the reactor. Never called by user code.
|
data/lib/zm/timers.rb
CHANGED
@@ -48,7 +48,11 @@ module ZMQMachine
|
|
48
48
|
#
|
49
49
|
class Timers
|
50
50
|
def initialize
|
51
|
-
@timers =
|
51
|
+
@timers = []
|
52
|
+
end
|
53
|
+
|
54
|
+
def list
|
55
|
+
@timers
|
52
56
|
end
|
53
57
|
|
54
58
|
# Adds a non-periodical, one-shot timer in order of
|
@@ -63,7 +67,7 @@ module ZMQMachine
|
|
63
67
|
return nil unless blk
|
64
68
|
|
65
69
|
timer = Timer.new self, delay, false, blk
|
66
|
-
|
70
|
+
add timer
|
67
71
|
timer
|
68
72
|
end
|
69
73
|
|
@@ -79,7 +83,7 @@ module ZMQMachine
|
|
79
83
|
return nil unless blk
|
80
84
|
|
81
85
|
timer = Timer.new self, delay, true, blk
|
82
|
-
|
86
|
+
add timer
|
83
87
|
timer
|
84
88
|
end
|
85
89
|
|
@@ -90,7 +94,13 @@ module ZMQMachine
|
|
90
94
|
# given +timer+.
|
91
95
|
#
|
92
96
|
def cancel timer
|
93
|
-
|
97
|
+
i = index timer
|
98
|
+
|
99
|
+
if timer == @timers.at(i)
|
100
|
+
@timers.delete_at(i) ? true : false
|
101
|
+
else
|
102
|
+
false
|
103
|
+
end
|
94
104
|
end
|
95
105
|
|
96
106
|
# A convenience method that loops through all known timers
|
@@ -102,31 +112,35 @@ module ZMQMachine
|
|
102
112
|
# is not yet expired; it knows all subsequent timers are not
|
103
113
|
# expired too.
|
104
114
|
#
|
115
|
+
# timers should be sorted by expiration time
|
116
|
+
# NOTE: was using #delete_if here, but it does *not* delete any
|
117
|
+
# items when the break executes before iterating through the entire
|
118
|
+
# set; that's unacceptable so I save each timer for deletion and
|
119
|
+
# do that in a separate loop
|
120
|
+
#
|
121
|
+
# Additionally, some timers may execute code paths that cancel other
|
122
|
+
# timers. If those timers are deleted while we are still iterating
|
123
|
+
# over them, the behavior is undefined (each runtime can handle it
|
124
|
+
# differently). To avoid that issue, we determine if they are expired
|
125
|
+
# and save them off for final processing outside of the loop. Any
|
126
|
+
# firing timer that deletes another timer will be safe.
|
127
|
+
#
|
105
128
|
def fire_expired
|
106
129
|
# all time is expected as milliseconds
|
107
130
|
now = Timers.now
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
# NOTE: was using #delete_if here, but it does *not* delete any
|
113
|
-
# items when the break executes before iterating through the entire
|
114
|
-
# set; that's unacceptable so I save each timer for deletion and
|
115
|
-
# do that in a separate loop
|
116
|
-
@timers.each do |timer|
|
131
|
+
runnables, periodicals, expired = [], [], []
|
132
|
+
|
133
|
+
# defer firing the timer until after this loop so we can clean it up first
|
134
|
+
@timers.each_with_index do |timer, index|
|
117
135
|
break unless timer.expired?(now)
|
118
|
-
timer
|
119
|
-
|
120
|
-
|
136
|
+
runnables << timer
|
137
|
+
periodicals << timer if timer.periodical?
|
138
|
+
expired << index
|
121
139
|
end
|
122
140
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
# since changing the timer.fire_time inside the loop would
|
127
|
-
# not retain proper ordering in the sorted set; re-adding it
|
128
|
-
# ensures the timers are in sorted order
|
129
|
-
save.each { |timer| @timers.add timer }
|
141
|
+
remove expired
|
142
|
+
runnables.each { |timer| timer.fire }
|
143
|
+
renew periodicals
|
130
144
|
end
|
131
145
|
|
132
146
|
# Runs through all timers and asks each one to reschedule itself
|
@@ -138,7 +152,7 @@ module ZMQMachine
|
|
138
152
|
|
139
153
|
timers.each do |timer|
|
140
154
|
timer.reschedule
|
141
|
-
|
155
|
+
add timer
|
142
156
|
end
|
143
157
|
end
|
144
158
|
|
@@ -160,6 +174,49 @@ module ZMQMachine
|
|
160
174
|
def self.now_converted
|
161
175
|
now / 1000.0
|
162
176
|
end
|
177
|
+
|
178
|
+
|
179
|
+
private
|
180
|
+
|
181
|
+
# inserts in order using a binary search (O(nlog n)) to find the
|
182
|
+
# index to insert; this scales nicely for situations where there
|
183
|
+
# are many thousands thousands of timers
|
184
|
+
def add timer
|
185
|
+
i = index timer
|
186
|
+
@timers.insert(i, timer)
|
187
|
+
end
|
188
|
+
|
189
|
+
# Original Ruby source Posted by Sergey Chernov (sergeych) on 2010-05-13 20:23
|
190
|
+
# http://www.ruby-forum.com/topic/134477
|
191
|
+
#
|
192
|
+
# binary search; assumes underlying array is already sorted
|
193
|
+
def index value
|
194
|
+
l, r = 0, @timers.size - 1
|
195
|
+
|
196
|
+
while l <= r
|
197
|
+
m = (r + l) / 2
|
198
|
+
if value < @timers.at(m)
|
199
|
+
r = m - 1
|
200
|
+
else
|
201
|
+
l = m + 1
|
202
|
+
end
|
203
|
+
end
|
204
|
+
l
|
205
|
+
end
|
206
|
+
|
207
|
+
def remove expired
|
208
|
+
# need to reverse so we are deleting the highest indexes first,
|
209
|
+
# otherwise everything shifts down and we delete the wrong timers
|
210
|
+
expired.sort.reverse.each { |index| @timers.delete_at index }
|
211
|
+
end
|
212
|
+
|
213
|
+
def renew timers
|
214
|
+
# reinstate the periodicals; necessary to do in two steps
|
215
|
+
# since changing the timer.fire_time inside the loop (in parent) would
|
216
|
+
# not retain proper ordering in the sorted list; re-adding it
|
217
|
+
# ensures the timers are in sorted order
|
218
|
+
timers.each { |timer| add timer }
|
219
|
+
end
|
163
220
|
end # class Timers
|
164
221
|
|
165
222
|
|
@@ -175,9 +232,9 @@ module ZMQMachine
|
|
175
232
|
class Timer
|
176
233
|
include Comparable
|
177
234
|
|
178
|
-
attr_reader :fire_time
|
235
|
+
attr_reader :fire_time, :timer_proc
|
179
236
|
|
180
|
-
# +
|
237
|
+
# +delay+ is in milliseconds
|
181
238
|
#
|
182
239
|
def initialize timers, delay, periodical, timer_proc = nil, &blk
|
183
240
|
@timers = timers
|
@@ -212,7 +269,7 @@ module ZMQMachine
|
|
212
269
|
# True when the timer should be fired; false otherwise.
|
213
270
|
#
|
214
271
|
def expired? time
|
215
|
-
time ||= now
|
272
|
+
time ||= Timers.now
|
216
273
|
time > @fire_time
|
217
274
|
end
|
218
275
|
|
@@ -225,6 +282,12 @@ module ZMQMachine
|
|
225
282
|
def reschedule
|
226
283
|
schedule_firing_time
|
227
284
|
end
|
285
|
+
|
286
|
+
def to_s
|
287
|
+
"[delay [#{@delay}], periodical? [#{@periodical}], fire_time [#{Time.at(@fire_time/1000)}] fire_delay_s [#{(@fire_time - Timers.now)/1000}]]"
|
288
|
+
end
|
289
|
+
|
290
|
+
def inspect; to_s; end
|
228
291
|
|
229
292
|
|
230
293
|
private
|
data/version.txt
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
data/zmqmachine.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{zmqmachine}
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.4.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Chuck Remes"]
|
9
|
-
s.date = %q{2010-
|
9
|
+
s.date = %q{2010-12-22}
|
10
10
|
s.description = %q{ZMQMachine is another Ruby implementation of the reactor pattern but this
|
11
11
|
time using 0mq sockets rather than POSIX sockets.
|
12
12
|
|
@@ -28,21 +28,21 @@ descriptors. This isn't on my roadmap but patches are accepted.}
|
|
28
28
|
s.require_paths = ["lib"]
|
29
29
|
s.rubyforge_project = %q{zmqmachine}
|
30
30
|
s.rubygems_version = %q{1.3.7}
|
31
|
-
s.summary = %q{ZMQMachine is another Ruby implementation of the reactor pattern but this time using 0mq sockets rather than POSIX sockets}
|
31
|
+
s.summary = %q{ZMQMachine is another Ruby implementation of the reactor pattern but this time using 0mq sockets rather than POSIX sockets.}
|
32
32
|
|
33
33
|
if s.respond_to? :specification_version then
|
34
34
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
35
35
|
s.specification_version = 3
|
36
36
|
|
37
37
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
38
|
-
s.add_runtime_dependency(%q<ffi-rzmq>, [">= 0.
|
39
|
-
s.add_development_dependency(%q<bones>, [">= 3.4
|
38
|
+
s.add_runtime_dependency(%q<ffi-rzmq>, [">= 0.7.0"])
|
39
|
+
s.add_development_dependency(%q<bones>, [">= 3.5.4"])
|
40
40
|
else
|
41
|
-
s.add_dependency(%q<ffi-rzmq>, [">= 0.
|
42
|
-
s.add_dependency(%q<bones>, [">= 3.4
|
41
|
+
s.add_dependency(%q<ffi-rzmq>, [">= 0.7.0"])
|
42
|
+
s.add_dependency(%q<bones>, [">= 3.5.4"])
|
43
43
|
end
|
44
44
|
else
|
45
|
-
s.add_dependency(%q<ffi-rzmq>, [">= 0.
|
46
|
-
s.add_dependency(%q<bones>, [">= 3.4
|
45
|
+
s.add_dependency(%q<ffi-rzmq>, [">= 0.7.0"])
|
46
|
+
s.add_dependency(%q<bones>, [">= 3.5.4"])
|
47
47
|
end
|
48
48
|
end
|
metadata
CHANGED
@@ -3,48 +3,50 @@ name: zmqmachine
|
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
version: 0.
|
6
|
+
- 0
|
7
|
+
- 4
|
8
|
+
- 0
|
9
|
+
version: 0.4.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
|
-
|
12
|
+
- Chuck Remes
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-12-22 00:00:00 -06:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: ffi-rzmq
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
- 7
|
31
|
+
- 0
|
32
|
+
version: 0.7.0
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: bones
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
segments:
|
44
|
+
- 3
|
45
|
+
- 5
|
46
|
+
- 4
|
47
|
+
version: 3.5.4
|
48
|
+
type: :development
|
49
|
+
version_requirements: *id002
|
48
50
|
description: |-
|
49
51
|
ZMQMachine is another Ruby implementation of the reactor pattern but this
|
50
52
|
time using 0mq sockets rather than POSIX sockets.
|
@@ -65,73 +67,75 @@ executables: []
|
|
65
67
|
extensions: []
|
66
68
|
|
67
69
|
extra_rdoc_files:
|
68
|
-
|
69
|
-
|
70
|
-
|
70
|
+
- History.txt
|
71
|
+
- README.rdoc
|
72
|
+
- version.txt
|
71
73
|
files:
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
74
|
+
- .bnsignore
|
75
|
+
- History.txt
|
76
|
+
- README.rdoc
|
77
|
+
- Rakefile
|
78
|
+
- examples/fake_ftp.rb
|
79
|
+
- examples/one_handed_ping_pong.rb
|
80
|
+
- examples/ping_pong.rb
|
81
|
+
- examples/pub_sub.rb
|
82
|
+
- examples/pubsub_forwarder.rb
|
83
|
+
- examples/throttled_ping_pong.rb
|
84
|
+
- lib/zm/address.rb
|
85
|
+
- lib/zm/deferrable.rb
|
86
|
+
- lib/zm/devices.rb
|
87
|
+
- lib/zm/devices/forwarder.rb
|
88
|
+
- lib/zm/devices/queue.rb
|
89
|
+
- lib/zm/exceptions.rb
|
90
|
+
- lib/zm/message.rb
|
91
|
+
- lib/zm/reactor.rb
|
92
|
+
- lib/zm/sockets.rb
|
93
|
+
- lib/zm/sockets/base.rb
|
94
|
+
- lib/zm/sockets/pair.rb
|
95
|
+
- lib/zm/sockets/pub.rb
|
96
|
+
- lib/zm/sockets/rep.rb
|
97
|
+
- lib/zm/sockets/req.rb
|
98
|
+
- lib/zm/sockets/sub.rb
|
99
|
+
- lib/zm/sockets/xrep.rb
|
100
|
+
- lib/zm/sockets/xreq.rb
|
101
|
+
- lib/zm/timers.rb
|
102
|
+
- lib/zmqmachine.rb
|
103
|
+
- spec/spec_helper.rb
|
104
|
+
- spec/zmqmachine_spec.rb
|
105
|
+
- version.txt
|
106
|
+
- zmqmachine.gemspec
|
105
107
|
has_rdoc: true
|
106
108
|
homepage: http://github.com/chuckremes/zmqmachine
|
107
109
|
licenses: []
|
108
110
|
|
109
111
|
post_install_message:
|
110
112
|
rdoc_options:
|
111
|
-
|
112
|
-
|
113
|
+
- --main
|
114
|
+
- README.rdoc
|
113
115
|
require_paths:
|
114
|
-
|
116
|
+
- lib
|
115
117
|
required_ruby_version: !ruby/object:Gem::Requirement
|
118
|
+
none: false
|
116
119
|
requirements:
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
segments:
|
123
|
+
- 0
|
124
|
+
version: "0"
|
122
125
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
126
|
+
none: false
|
123
127
|
requirements:
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
segments:
|
131
|
+
- 0
|
132
|
+
version: "0"
|
129
133
|
requirements: []
|
130
134
|
|
131
135
|
rubyforge_project: zmqmachine
|
132
|
-
rubygems_version: 1.3.
|
136
|
+
rubygems_version: 1.3.7
|
133
137
|
signing_key:
|
134
138
|
specification_version: 3
|
135
|
-
summary: ZMQMachine is another Ruby implementation of the reactor pattern but this time using 0mq sockets rather than POSIX sockets
|
139
|
+
summary: ZMQMachine is another Ruby implementation of the reactor pattern but this time using 0mq sockets rather than POSIX sockets.
|
136
140
|
test_files: []
|
137
141
|
|