amqp 0.7.5 → 0.8.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -4
- data/.travis.yml +3 -5
- data/.yardopts +6 -0
- data/CHANGELOG +26 -7
- data/Gemfile +15 -7
- data/README.textile +216 -0
- data/Rakefile +0 -6
- data/amqp.gemspec +14 -4
- data/bin/jenkins.sh +27 -0
- data/bin/set_test_suite_realms_up.sh +16 -2
- data/docs/VendorSpecificExtensions.textile +32 -0
- data/examples/extensions/rabbitmq/publisher_confirmations_with_transient_messages.rb +53 -0
- data/examples/hello_world.rb +29 -0
- data/examples/real-world/task-queue/README.textile +3 -0
- data/examples/real-world/task-queue/consumer.rb +27 -0
- data/examples/real-world/task-queue/producer.rb +22 -0
- data/examples/various/ack.rb +70 -0
- data/examples/various/automatic_binding_for_default_direct_exchange.rb +53 -0
- data/examples/various/basic_get.rb +65 -0
- data/examples/various/callbacks.rb +45 -0
- data/examples/various/clock.rb +74 -0
- data/examples/various/declare_a_queue_without_assignment.rb +46 -0
- data/examples/various/declare_an_exchange_without_assignment.rb +46 -0
- data/examples/various/hashtable.rb +60 -0
- data/examples/{logger.rb → various/logger.rb} +9 -7
- data/examples/{multiclock.rb → various/multiclock.rb} +15 -17
- data/examples/various/open_channel_without_assignment.rb +34 -0
- data/examples/various/pingpong.rb +53 -0
- data/examples/various/primes-simple.rb +29 -0
- data/examples/various/primes.rb +76 -0
- data/examples/various/pubsub.rb +43 -0
- data/examples/various/queue_status.rb +58 -0
- data/examples/various/stocks.rb +59 -0
- data/examples/various/weather_updates.rb +63 -0
- data/lib/amqp.rb +11 -2
- data/lib/amqp/basic_client.rb +23 -54
- data/lib/amqp/channel.rb +577 -805
- data/lib/amqp/client.rb +37 -275
- data/lib/amqp/connection.rb +165 -93
- data/lib/amqp/deprecated/fork.rb +15 -0
- data/lib/amqp/deprecated/logger.rb +99 -0
- data/lib/amqp/deprecated/mq.rb +20 -0
- data/lib/amqp/deprecated/rpc.rb +168 -0
- data/lib/amqp/exchange.rb +409 -281
- data/lib/amqp/extensions/rabbitmq.rb +1 -0
- data/lib/amqp/header.rb +41 -17
- data/lib/amqp/logger.rb +10 -84
- data/lib/amqp/queue.rb +457 -320
- data/lib/amqp/rpc.rb +11 -107
- data/lib/amqp/version.rb +1 -1
- data/lib/mq.rb +2 -1
- data/lib/mq/logger.rb +2 -0
- data/lib/mq/rpc.rb +2 -0
- data/spec/integration/authentication_spec.rb +36 -40
- data/spec/integration/automatic_binding_for_default_direct_exchange_spec.rb +3 -5
- data/spec/integration/basic_get_spec.rb +91 -0
- data/spec/integration/channel_close_spec.rb +5 -5
- data/spec/integration/exchange_declaration_spec.rb +6 -53
- data/spec/integration/extensions/basic_return_spec.rb +47 -0
- data/spec/integration/queue_declaration_spec.rb +14 -17
- data/spec/integration/queue_exclusivity_spec.rb +49 -48
- data/spec/integration/reply_queue_communication_spec.rb +6 -4
- data/spec/integration/store_and_forward_spec.rb +9 -36
- data/spec/integration/topic_subscription_spec.rb +1 -1
- data/spec/integration/workload_distribution_spec.rb +1 -0
- data/spec/spec_helper.rb +69 -43
- data/spec/unit/amqp/connection_spec.rb +27 -23
- data/tasks.rb +11 -0
- metadata +124 -95
- data/README.md +0 -156
- data/TODO +0 -30
- data/amqp.pre.gemspec +0 -6
- data/examples/ack.rb +0 -47
- data/examples/automatic_binding_for_default_direct_exchange.rb +0 -65
- data/examples/callbacks.rb +0 -40
- data/examples/clock.rb +0 -65
- data/examples/default_channel.rb +0 -19
- data/examples/hashtable.rb +0 -61
- data/examples/immediately_bind_a_server_named_queue.rb +0 -38
- data/examples/internal.rb +0 -51
- data/examples/issues/issue_75.rb +0 -21
- data/examples/issues/issue_94.rb +0 -23
- data/examples/pingpong.rb +0 -54
- data/examples/pop.rb +0 -45
- data/examples/primes-simple.rb +0 -21
- data/examples/primes.rb +0 -101
- data/examples/simple.rb +0 -81
- data/examples/stocks.rb +0 -67
- data/gemfiles/eventmachine-pre +0 -24
- data/lib/amqp/buffer.rb +0 -272
- data/lib/amqp/collection.rb +0 -60
- data/lib/amqp/frame.rb +0 -68
- data/lib/amqp/protocol.rb +0 -163
- data/lib/amqp/server.rb +0 -101
- data/lib/amqp/spec.rb +0 -832
- data/protocol/amqp-0.8.json +0 -617
- data/protocol/amqp-0.8.xml +0 -3908
- data/protocol/codegen.rb +0 -175
- data/protocol/doc.txt +0 -281
- data/research/api.rb +0 -52
- data/research/primes-forked.rb +0 -65
- data/research/primes-processes.rb +0 -137
- data/research/primes-threaded.rb +0 -51
- data/spec/integration/queue_status_spec.rb +0 -44
- data/spec/unit/amqp/buffer_spec.rb +0 -178
- data/spec/unit/amqp/client_spec.rb +0 -102
- data/spec/unit/amqp/collection_spec.rb +0 -144
- data/spec/unit/amqp/frame_spec.rb +0 -60
- data/spec/unit/amqp/protocol_spec.rb +0 -51
@@ -0,0 +1,46 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "bundler"
|
5
|
+
Bundler.setup
|
6
|
+
|
7
|
+
$:.unshift(File.expand_path("../../../lib", __FILE__))
|
8
|
+
|
9
|
+
require 'amqp'
|
10
|
+
|
11
|
+
|
12
|
+
puts "=> Queue#initialize example that uses a block"
|
13
|
+
puts
|
14
|
+
AMQP.start("amqp://guest:guest@dev.rabbitmq.com:5672/") do |connection, open_ok|
|
15
|
+
AMQP::Channel.new do |channel, open_ok|
|
16
|
+
puts "Channel ##{channel.id} is now open!"
|
17
|
+
|
18
|
+
AMQP::Queue.new(channel, "", :auto_delete => true) do |queue|
|
19
|
+
puts "#{queue.name} is ready to go"
|
20
|
+
end
|
21
|
+
|
22
|
+
AMQP::Queue.new(channel, "", :auto_delete => true) do |queue, declare_ok|
|
23
|
+
puts "#{queue.name} is ready to go. AMQP method: #{declare_ok.inspect}"
|
24
|
+
end
|
25
|
+
|
26
|
+
channel.queue("", :auto_delete => true) do |queue, declare_ok|
|
27
|
+
puts "#{queue.name} is ready to go. AMQP method: #{declare_ok.inspect}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
show_stopper = Proc.new do
|
33
|
+
$stdout.puts "Stopping..."
|
34
|
+
|
35
|
+
# queue.purge :nowait => true
|
36
|
+
|
37
|
+
# now change this to just EM.stop and it
|
38
|
+
# unbinds instantly
|
39
|
+
connection.close {
|
40
|
+
EM.stop { exit }
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
Signal.trap "INT", show_stopper
|
45
|
+
EM.add_timer(2, show_stopper)
|
46
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "bundler"
|
5
|
+
Bundler.setup
|
6
|
+
|
7
|
+
$:.unshift(File.expand_path("../../../lib", __FILE__))
|
8
|
+
|
9
|
+
require 'amqp'
|
10
|
+
|
11
|
+
|
12
|
+
puts "=> Exchange#initialize example that uses a block"
|
13
|
+
puts
|
14
|
+
AMQP.start(:host => 'localhost') do |connection|
|
15
|
+
AMQP::Channel.new do |channel, open_ok|
|
16
|
+
puts "Channel ##{channel.id} is now open!"
|
17
|
+
|
18
|
+
AMQP::Exchange.new(channel, :direct, "amqpgem.examples.xchange1", :auto_delete => true) do |exchange|
|
19
|
+
puts "#{exchange.name} is ready to go"
|
20
|
+
end
|
21
|
+
|
22
|
+
AMQP::Exchange.new(channel, :direct, "amqpgem.examples.xchange1", :auto_delete => true) do |exchange, declare_ok|
|
23
|
+
puts "#{exchange.name} is ready to go. AMQP method: #{declare_ok.inspect}"
|
24
|
+
end
|
25
|
+
|
26
|
+
channel.direct("amqpgem.examples.xchange2", :auto_delete => true) do |exchange, declare_ok|
|
27
|
+
puts "#{exchange.name} is ready to go. AMQP method: #{declare_ok.inspect}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
show_stopper = Proc.new do
|
33
|
+
$stdout.puts "Stopping..."
|
34
|
+
|
35
|
+
# queue.purge :nowait => true
|
36
|
+
|
37
|
+
# now change this to just EM.stop and it
|
38
|
+
# unbinds instantly
|
39
|
+
connection.close {
|
40
|
+
EM.stop { exit }
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
Signal.trap "INT", show_stopper
|
45
|
+
EM.add_timer(2, show_stopper)
|
46
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "bundler"
|
5
|
+
Bundler.setup
|
6
|
+
|
7
|
+
$:.unshift(File.expand_path("../../../lib", __FILE__))
|
8
|
+
require 'amqp'
|
9
|
+
|
10
|
+
|
11
|
+
def log(*args)
|
12
|
+
p args
|
13
|
+
end
|
14
|
+
|
15
|
+
# AMQP.logging = true
|
16
|
+
|
17
|
+
class HashTable < Hash
|
18
|
+
def get(key)
|
19
|
+
self[key]
|
20
|
+
end
|
21
|
+
|
22
|
+
def set(key, value)
|
23
|
+
self[key] = value
|
24
|
+
end
|
25
|
+
|
26
|
+
def keys
|
27
|
+
super
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
AMQP.start(:host => 'localhost') do |connection|
|
32
|
+
trap(:INT) do
|
33
|
+
unless connection.closing?
|
34
|
+
connection.close { exit! }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
channel = AMQP::Channel.new(connection)
|
39
|
+
server = channel.rpc('hash table node', HashTable.new)
|
40
|
+
client = channel.rpc('hash table node')
|
41
|
+
|
42
|
+
client.set(:protocol, "amqp")
|
43
|
+
client.get(:protocol) do |res|
|
44
|
+
log 'client', :protocol_get_res => res
|
45
|
+
end
|
46
|
+
|
47
|
+
client.set(:now, time = Time.now)
|
48
|
+
client.get(:now) do |res|
|
49
|
+
log 'client', :now => res, :eql? => res == time
|
50
|
+
end
|
51
|
+
|
52
|
+
client.set(:one, 1)
|
53
|
+
client.keys do |res|
|
54
|
+
log 'client', :keys => res
|
55
|
+
end
|
56
|
+
|
57
|
+
EM.add_timer(3, Proc.new {
|
58
|
+
AMQP.stop { EM.stop }
|
59
|
+
})
|
60
|
+
end
|
@@ -1,15 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
1
2
|
# encoding: utf-8
|
2
3
|
|
3
|
-
|
4
|
+
require "bundler"
|
5
|
+
Bundler.setup
|
6
|
+
|
7
|
+
$:.unshift(File.expand_path("../../../lib", __FILE__))
|
4
8
|
require 'amqp'
|
5
9
|
require 'amqp/logger'
|
6
10
|
|
7
|
-
Logger = AMQP::Channel::Logger
|
8
|
-
|
9
11
|
AMQP.start(:host => 'localhost') do
|
10
12
|
if ARGV[0] == 'server'
|
11
13
|
|
12
|
-
AMQP::Channel.queue('logger').bind(AMQP::Channel.fanout('logging', :durable => true)).subscribe { |msg|
|
14
|
+
AMQP::Channel.new.queue('logger').bind(AMQP::Channel.new.fanout('logging', :durable => true)).subscribe { |msg|
|
13
15
|
msg = Marshal.load(msg)
|
14
16
|
require 'pp'
|
15
17
|
pp(msg)
|
@@ -18,10 +20,10 @@ AMQP.start(:host => 'localhost') do
|
|
18
20
|
|
19
21
|
elsif ARGV[0] == 'client'
|
20
22
|
|
21
|
-
log = Logger.new
|
23
|
+
log = AMQP::Logger.new
|
22
24
|
log.debug 'its working!'
|
23
25
|
|
24
|
-
log = Logger.new do |msg|
|
26
|
+
log = AMQP::Logger.new do |msg|
|
25
27
|
require 'pp'
|
26
28
|
pp msg
|
27
29
|
puts
|
@@ -36,7 +38,7 @@ AMQP.start(:host => 'localhost') do
|
|
36
38
|
log.info '123', :process
|
37
39
|
log.debug 'login', :session => 'abc', :user => 123
|
38
40
|
|
39
|
-
log = Logger.new(:webserver, :timestamp, :hostname, &log.printer)
|
41
|
+
log = AMQP::Logger.new(:webserver, :timestamp, :hostname, &log.printer)
|
40
42
|
log.info 'Request for /', :GET, :session => 'abc'
|
41
43
|
|
42
44
|
AMQP.stop { EM.stop }
|
@@ -1,6 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
1
2
|
# encoding: utf-8
|
2
3
|
|
3
|
-
|
4
|
+
require "bundler"
|
5
|
+
Bundler.setup
|
6
|
+
|
7
|
+
$:.unshift(File.expand_path("../../../lib", __FILE__))
|
4
8
|
require 'amqp'
|
5
9
|
require 'time'
|
6
10
|
|
@@ -27,7 +31,7 @@ AMQP.start(:host => 'localhost') do |connection|
|
|
27
31
|
["iso8601", "rfc2822"].each do |format|
|
28
32
|
formatted_time = time.send(format)
|
29
33
|
log :publish, format, formatted_time
|
30
|
-
clock.publish "#{formatted_time}", :headers => {"format" => format}
|
34
|
+
clock.publish "#{formatted_time}", :headers => {"format" => format} if connection.open?
|
31
35
|
end
|
32
36
|
}
|
33
37
|
|
@@ -38,21 +42,15 @@ AMQP.start(:host => 'localhost') do |connection|
|
|
38
42
|
}
|
39
43
|
end
|
40
44
|
|
41
|
-
|
42
|
-
|
43
|
-
|
45
|
+
show_stopper = Proc.new {
|
46
|
+
connection.close do
|
47
|
+
EM.stop
|
48
|
+
end
|
49
|
+
}
|
44
50
|
|
45
|
-
|
46
|
-
|
47
|
-
["received iso8601", "2009-02-13T19:55:40-08:00"]
|
48
|
-
["received rfc2822", "Fri, 13 Feb 2009 19:55:40 -0800"]
|
51
|
+
Signal.trap "INT", show_stopper
|
52
|
+
Signal.trap "TERM", show_stopper
|
49
53
|
|
50
|
-
|
51
|
-
[:publish, "rfc2822", "Fri, 13 Feb 2009 19:55:41 -0800"]
|
52
|
-
["received iso8601", "2009-02-13T19:55:41-08:00"]
|
53
|
-
["received rfc2822", "Fri, 13 Feb 2009 19:55:41 -0800"]
|
54
|
+
EM.add_timer(3, show_stopper)
|
54
55
|
|
55
|
-
|
56
|
-
[:publish, "rfc2822", "Fri, 13 Feb 2009 19:55:42 -0800"]
|
57
|
-
["received iso8601", "2009-02-13T19:55:42-08:00"]
|
58
|
-
["received rfc2822", "Fri, 13 Feb 2009 19:55:42 -0800"]
|
56
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "bundler"
|
5
|
+
Bundler.setup
|
6
|
+
|
7
|
+
$:.unshift(File.expand_path("../../../lib", __FILE__))
|
8
|
+
|
9
|
+
require 'amqp'
|
10
|
+
|
11
|
+
|
12
|
+
puts "=> Channel#initialize example that uses a block"
|
13
|
+
puts
|
14
|
+
AMQP.start(:host => 'localhost') do |connection|
|
15
|
+
AMQP::Channel.new do |channel, open_ok|
|
16
|
+
puts "Channel ##{channel.id} is now open!"
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
show_stopper = Proc.new do
|
21
|
+
$stdout.puts "Stopping..."
|
22
|
+
|
23
|
+
# queue.purge :nowait => true
|
24
|
+
|
25
|
+
# now change this to just EM.stop and it
|
26
|
+
# unbinds instantly
|
27
|
+
connection.close {
|
28
|
+
EM.stop { exit }
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
Signal.trap "INT", show_stopper
|
33
|
+
EM.add_timer(2, show_stopper)
|
34
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "bundler"
|
5
|
+
Bundler.setup
|
6
|
+
|
7
|
+
$:.unshift(File.expand_path("../../../lib", __FILE__))
|
8
|
+
require 'amqp'
|
9
|
+
|
10
|
+
AMQP.start(:host => 'localhost') do |connection|
|
11
|
+
def log(*args)
|
12
|
+
p [ Time.now, *args ]
|
13
|
+
end
|
14
|
+
|
15
|
+
# AMQP.logging = true
|
16
|
+
|
17
|
+
amq = AMQP::Channel.new(connection)
|
18
|
+
exchange = amq.default_exchange
|
19
|
+
q1 = amq.queue('one')
|
20
|
+
q2 = amq.queue('two')
|
21
|
+
|
22
|
+
EM.add_periodic_timer(1) {
|
23
|
+
puts
|
24
|
+
|
25
|
+
log :sending, 'ping'
|
26
|
+
exchange.publish("ping", :routing_key => "one")
|
27
|
+
}
|
28
|
+
|
29
|
+
2.times do
|
30
|
+
q1.publish('ping', :routing_key => "one")
|
31
|
+
end
|
32
|
+
|
33
|
+
q1.subscribe do |msg|
|
34
|
+
log 'one', :received, msg, :sending, 'pong'
|
35
|
+
exchange.publish('pong', :routing_key => "two")
|
36
|
+
end
|
37
|
+
q2.subscribe { |msg| log('two', :received, msg) }
|
38
|
+
|
39
|
+
show_stopper = Proc.new do
|
40
|
+
$stdout.puts "Stopping..."
|
41
|
+
# now change this to just EM.stop and it
|
42
|
+
# unbinds instantly
|
43
|
+
connection.close {
|
44
|
+
EM.stop { exit }
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
Signal.trap "INT", show_stopper
|
49
|
+
Signal.trap "TERM", show_stopper
|
50
|
+
|
51
|
+
EM.add_timer(3, show_stopper)
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
# You are probably wondering what the smeg is this example all about.
|
5
|
+
# Check examples/primes.rb, the only point of this file is to compare
|
6
|
+
# with its RPC implementation.
|
7
|
+
|
8
|
+
require "bundler"
|
9
|
+
Bundler.setup
|
10
|
+
|
11
|
+
MAX = 1000
|
12
|
+
|
13
|
+
class Fixnum
|
14
|
+
def prime?
|
15
|
+
('1' * self) !~ /^1?$|^(11+?)\1+$/
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class PrimeChecker
|
20
|
+
def is_prime?(number)
|
21
|
+
number.prime?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
prime_checker = PrimeChecker.new
|
26
|
+
|
27
|
+
(10_000...(10_000 + MAX)).each do |n|
|
28
|
+
prime_checker.is_prime?(n)
|
29
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
require "bundler"
|
5
|
+
Bundler.setup
|
6
|
+
|
7
|
+
$:.unshift(File.expand_path("../../../lib", __FILE__))
|
8
|
+
require 'amqp'
|
9
|
+
|
10
|
+
# check MAX numbers for prime-ness
|
11
|
+
MAX = 1000
|
12
|
+
|
13
|
+
# logging
|
14
|
+
def log(*args)
|
15
|
+
p args
|
16
|
+
end
|
17
|
+
|
18
|
+
# spawn workers
|
19
|
+
workers = ARGV[0] ? (Integer(ARGV[0]) rescue 1) : 1
|
20
|
+
AMQP.fork(workers) do # TODO: AMQP.fork isn't implemented and I'm not sure if it should be implemented, it looks pretty damn ugly.
|
21
|
+
log AMQP::Channel.id, :started
|
22
|
+
|
23
|
+
class Fixnum
|
24
|
+
def prime?
|
25
|
+
('1' * self) !~ /^1?$|^(11+?)\1+$/
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class PrimeChecker
|
30
|
+
def is_prime? number
|
31
|
+
log "prime checker #{AMQP::Channel.id}", :prime?, number
|
32
|
+
number.prime?
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# This is the server part of RPC.
|
37
|
+
# Everything we'll call on the client part will be actually
|
38
|
+
# marshalled and published to a queue which the server part
|
39
|
+
# consumes and executes.
|
40
|
+
AMQP::Channel.new.rpc('prime checker', PrimeChecker.new)
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
# use workers to check which numbers are prime
|
45
|
+
AMQP.start(:host => 'localhost') do |connection|
|
46
|
+
|
47
|
+
show_stopper = Proc.new do
|
48
|
+
$stdout.puts "Stopping..."
|
49
|
+
# now change this to just EM.stop and it
|
50
|
+
# unbinds instantly
|
51
|
+
connection.close {
|
52
|
+
EM.stop { exit }
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
prime_checker = AMQP::Channel.new.rpc('prime checker')
|
57
|
+
|
58
|
+
(10_000...(10_000 + MAX)).each do |num|
|
59
|
+
log :checking, num
|
60
|
+
|
61
|
+
prime_checker.is_prime?(num) { |is_prime|
|
62
|
+
log :prime?, num, is_prime
|
63
|
+
(@primes ||= []) << num if is_prime
|
64
|
+
|
65
|
+
if (@responses = (@responses || 0) + 1) == MAX
|
66
|
+
log :primes=, @primes
|
67
|
+
show_stopper.call
|
68
|
+
end
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
Signal.trap "INT", show_stopper
|
73
|
+
Signal.trap "TERM", show_stopper
|
74
|
+
|
75
|
+
EM.add_timer(5, show_stopper)
|
76
|
+
end
|