zmqmachine 0.3.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|