amqp 0.7.0 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -2
- data/CHANGELOG +25 -0
- data/Gemfile +4 -2
- data/README.md +2 -0
- data/{amqp.todo → TODO} +1 -3
- data/amqp.gemspec +3 -3
- data/bin/irb +2 -2
- data/bin/jenkins.sh +25 -0
- data/bin/set_test_suite_realms_up.sh +21 -0
- data/doc/EXAMPLE_01_PINGPONG +1 -1
- data/doc/EXAMPLE_02_CLOCK +1 -1
- data/doc/EXAMPLE_03_STOCKS +1 -1
- data/doc/EXAMPLE_04_MULTICLOCK +1 -1
- data/doc/EXAMPLE_05_ACK +1 -1
- data/doc/EXAMPLE_05_POP +1 -1
- data/doc/EXAMPLE_06_HASHTABLE +1 -1
- data/examples/{mq/ack.rb → ack.rb} +6 -6
- data/examples/{mq/automatic_binding_for_default_direct_exchange.rb → automatic_binding_for_default_direct_exchange.rb} +4 -4
- data/examples/{mq/callbacks.rb → callbacks.rb} +2 -2
- data/examples/{mq/clock.rb → clock.rb} +5 -5
- data/examples/{mq/hashtable.rb → hashtable.rb} +4 -4
- data/examples/{mq/internal.rb → internal.rb} +5 -5
- data/examples/{mq/logger.rb → logger.rb} +5 -5
- data/examples/{mq/multiclock.rb → multiclock.rb} +4 -4
- data/examples/{mq/pingpong.rb → pingpong.rb} +5 -5
- data/examples/{mq/pop.rb → pop.rb} +3 -3
- data/examples/{mq/primes-simple.rb → primes-simple.rb} +0 -0
- data/examples/{mq/primes.rb → primes.rb} +6 -6
- data/examples/{amqp/simple.rb → simple.rb} +1 -1
- data/examples/{mq/stocks.rb → stocks.rb} +5 -5
- data/lib/amqp.rb +8 -112
- data/lib/amqp/basic_client.rb +58 -0
- data/lib/amqp/channel.rb +937 -0
- data/lib/amqp/client.rb +72 -79
- data/lib/{mq → amqp}/collection.rb +12 -2
- data/lib/amqp/connection.rb +115 -0
- data/lib/amqp/exceptions.rb +18 -0
- data/lib/{mq → amqp}/exchange.rb +32 -34
- data/lib/{ext → amqp/ext}/em.rb +1 -1
- data/lib/{ext → amqp/ext}/emfork.rb +0 -0
- data/lib/amqp/frame.rb +3 -3
- data/lib/{mq → amqp}/header.rb +5 -11
- data/lib/{mq → amqp}/logger.rb +2 -2
- data/lib/amqp/protocol.rb +2 -2
- data/lib/{mq → amqp}/queue.rb +20 -17
- data/lib/{mq → amqp}/rpc.rb +20 -8
- data/lib/amqp/server.rb +1 -1
- data/lib/amqp/version.rb +1 -1
- data/lib/mq.rb +20 -964
- data/protocol/codegen.rb +1 -1
- data/research/api.rb +3 -3
- data/research/primes-forked.rb +5 -5
- data/research/primes-processes.rb +5 -5
- data/research/primes-threaded.rb +5 -5
- data/spec/integration/authentication_spec.rb +114 -0
- data/spec/integration/automatic_binding_for_default_direct_exchange_spec.rb +13 -12
- data/spec/{unit/mq → integration}/channel_close_spec.rb +2 -2
- data/spec/{unit/mq → integration}/exchange_declaration_spec.rb +26 -14
- data/spec/{unit/mq → integration}/queue_declaration_spec.rb +4 -4
- data/spec/integration/queue_exclusivity_spec.rb +95 -0
- data/spec/integration/reply_queue_communication_spec.rb +63 -0
- data/spec/integration/store_and_forward_spec.rb +121 -0
- data/spec/integration/topic_subscription_spec.rb +193 -0
- data/spec/integration/workload_distribution_spec.rb +245 -0
- data/spec/spec_helper.rb +16 -32
- data/spec/unit/{mq/mq_basic_spec.rb → amqp/basic_spec.rb} +4 -4
- data/spec/unit/{mq → amqp}/collection_spec.rb +22 -7
- data/spec/unit/amqp/connection_spec.rb +116 -0
- data/spec/unit/amqp/frame_spec.rb +18 -18
- data/spec/unit/amqp/protocol_spec.rb +9 -11
- metadata +54 -49
- data/lib/ext/blankslate.rb +0 -9
- data/spec/mq_helper.rb +0 -70
- data/spec/unit/amqp/client_spec.rb +0 -472
- data/spec/unit/amqp/misc_spec.rb +0 -123
- data/spec/unit/mq/misc_spec.rb +0 -228
- data/spec/unit/mq/queue_spec.rb +0 -71
data/protocol/codegen.rb
CHANGED
data/research/api.rb
CHANGED
@@ -31,11 +31,11 @@ AMQP.start do |amqp|
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
def
|
35
|
-
(Thread.current[:mq] ||=
|
34
|
+
def AMQP::Channel.method_missing meth, *args, &blk
|
35
|
+
(Thread.current[:mq] ||= AMQP::Channel.new).__send__(meth, *args, &blk)
|
36
36
|
end
|
37
37
|
|
38
|
-
mq =
|
38
|
+
mq = AMQP::Channel.new
|
39
39
|
mq.direct.publish('alkjsdf', :key => 'name')
|
40
40
|
mq.topic # 'amq.topic'
|
41
41
|
mq.topic('test').publish('some data', :key => 'stock.usd.*')
|
data/research/primes-forked.rb
CHANGED
@@ -23,7 +23,7 @@ def log(*args)
|
|
23
23
|
p args
|
24
24
|
end
|
25
25
|
|
26
|
-
#
|
26
|
+
# AMQP::Channel.logging = true
|
27
27
|
|
28
28
|
# worker
|
29
29
|
|
@@ -39,10 +39,10 @@ end
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
|
42
|
+
AMQP::Channel.queue('prime checker').subscribe { |info, num|
|
43
43
|
log "prime checker #{Process.pid}", :prime?, num
|
44
44
|
if Integer(num).prime?
|
45
|
-
|
45
|
+
AMQP::Channel.queue(info.reply_to).publish(num, :reply_to => Process.pid)
|
46
46
|
end
|
47
47
|
}
|
48
48
|
}
|
@@ -51,7 +51,7 @@ end
|
|
51
51
|
# controller
|
52
52
|
|
53
53
|
EM.run {
|
54
|
-
|
54
|
+
AMQP::Channel.queue('prime collector').subscribe { |info, prime|
|
55
55
|
log 'prime collector', :received, prime, :from, info.reply_to
|
56
56
|
(@primes ||= []) << Integer(prime)
|
57
57
|
EM.stop_event_loop if prime == '499'
|
@@ -59,7 +59,7 @@ end
|
|
59
59
|
|
60
60
|
MAX.times do |i|
|
61
61
|
EM.next_tick do
|
62
|
-
|
62
|
+
AMQP::Channel.queue('prime checker').publish((i+1).to_s, :reply_to => 'prime collector')
|
63
63
|
end
|
64
64
|
end
|
65
65
|
}
|
@@ -11,7 +11,7 @@ EM.run {
|
|
11
11
|
p args
|
12
12
|
end
|
13
13
|
|
14
|
-
#
|
14
|
+
# AMQP::Channel.logging = true
|
15
15
|
|
16
16
|
if ARGV[0] == 'worker'
|
17
17
|
|
@@ -23,24 +23,24 @@ EM.run {
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
|
26
|
+
AMQP::Channel.queue('prime checker').subscribe { |info, num|
|
27
27
|
log "prime checker #{Process.pid}", :prime?, num
|
28
28
|
if Integer(num).prime?
|
29
|
-
|
29
|
+
AMQP::Channel.queue(info.reply_to).publish(num, :reply_to => Process.pid)
|
30
30
|
EM.stop_event_loop if num == (MAX-1).to_s
|
31
31
|
end
|
32
32
|
}
|
33
33
|
|
34
34
|
elsif ARGV[0] == 'controller'
|
35
35
|
|
36
|
-
|
36
|
+
AMQP::Channel.queue('prime collector').subscribe { |info, prime|
|
37
37
|
log 'prime collector', :received, prime, :from, info.reply_to
|
38
38
|
(@primes ||= []) << Integer(prime)
|
39
39
|
}
|
40
40
|
|
41
41
|
MAX.times do |i|
|
42
42
|
EM.next_tick do
|
43
|
-
|
43
|
+
AMQP::Channel.queue('prime checker').publish((i+1).to_s, :reply_to => 'prime collector')
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
data/research/primes-threaded.rb
CHANGED
@@ -9,7 +9,7 @@ def log(*args)
|
|
9
9
|
p args
|
10
10
|
end
|
11
11
|
|
12
|
-
#
|
12
|
+
# AMQP::Channel.logging = true
|
13
13
|
|
14
14
|
EM.run {
|
15
15
|
|
@@ -23,12 +23,12 @@ EM.run {
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
|
26
|
+
AMQP::Channel.queue('prime checker').subscribe { |info, num|
|
27
27
|
EM.defer(proc {
|
28
28
|
|
29
29
|
log "prime checker #{Process.pid}-#{Thread.current.object_id}", :prime?, num
|
30
30
|
if Integer(num).prime?
|
31
|
-
|
31
|
+
AMQP::Channel.queue(info.reply_to).publish(num, :reply_to => "#{Process.pid}-#{Thread.current.object_id}")
|
32
32
|
EM.stop_event_loop if num == '499'
|
33
33
|
end
|
34
34
|
|
@@ -37,14 +37,14 @@ EM.run {
|
|
37
37
|
|
38
38
|
# controller
|
39
39
|
|
40
|
-
|
40
|
+
AMQP::Channel.queue('prime collector').subscribe { |info, prime|
|
41
41
|
log 'prime collector', :received, prime, :from, info.reply_to
|
42
42
|
(@primes ||= []) << Integer(prime)
|
43
43
|
}
|
44
44
|
|
45
45
|
MAX.times do |i|
|
46
46
|
EM.next_tick do
|
47
|
-
|
47
|
+
AMQP::Channel.queue('prime checker').publish((i+1).to_s, :reply_to => 'prime collector')
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
describe "Authentication attempt" do
|
5
|
+
|
6
|
+
#
|
7
|
+
# Environment
|
8
|
+
#
|
9
|
+
|
10
|
+
include AMQP::Spec
|
11
|
+
include AMQP::SpecHelper
|
12
|
+
|
13
|
+
em_before { AMQP.cleanup_state }
|
14
|
+
em_after { AMQP.cleanup_state }
|
15
|
+
|
16
|
+
describe "with default connection parameters" do
|
17
|
+
|
18
|
+
#
|
19
|
+
# Examples
|
20
|
+
#
|
21
|
+
|
22
|
+
# assuming there is an account guest with password of "guest" that has
|
23
|
+
# access to / (default vhost)
|
24
|
+
context "when guest/guest has access to /" do
|
25
|
+
after :all do
|
26
|
+
done
|
27
|
+
end
|
28
|
+
|
29
|
+
it "succeeds" do
|
30
|
+
connection = AMQP.connect
|
31
|
+
|
32
|
+
done(0.3) {
|
33
|
+
connection.should be_connected
|
34
|
+
connection.close
|
35
|
+
}
|
36
|
+
end # it
|
37
|
+
end # context
|
38
|
+
end # describe
|
39
|
+
|
40
|
+
|
41
|
+
describe "with explicitly given connection parameters" do
|
42
|
+
|
43
|
+
#
|
44
|
+
# Examples
|
45
|
+
#
|
46
|
+
|
47
|
+
# assuming there is an account amqp_gem with password of "amqp_gem_password" that has
|
48
|
+
# access to /amqp_gem_testbed
|
49
|
+
context "when amqp_gem/amqp_gem_testbed has access to /amqp_gem_testbed" do
|
50
|
+
after :all do
|
51
|
+
done
|
52
|
+
end
|
53
|
+
|
54
|
+
context "and provided credentials are correct" do
|
55
|
+
it "succeeds" do
|
56
|
+
connection = AMQP.connect :username => "amqp_gem", :password => "amqp_gem_password", :vhost => "/amqp_gem_testbed"
|
57
|
+
|
58
|
+
done(0.3) {
|
59
|
+
connection.should be_connected
|
60
|
+
connection.close
|
61
|
+
}
|
62
|
+
end # it
|
63
|
+
end # context
|
64
|
+
|
65
|
+
context "and provided credentials ARE INCORRECT" do
|
66
|
+
it "fails" do
|
67
|
+
connection = AMQP.connect :user => "amqp_gem", :pass => Time.now.to_i.to_s, :vhost => "/amqp_gem_testbed"
|
68
|
+
|
69
|
+
done(0.5) {
|
70
|
+
connection.should_not be_connected
|
71
|
+
}
|
72
|
+
end # it
|
73
|
+
end
|
74
|
+
end # context
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
describe "with connection string" do
|
79
|
+
|
80
|
+
#
|
81
|
+
# Examples
|
82
|
+
#
|
83
|
+
|
84
|
+
# assuming there is an account amqp_gem with password of "amqp_gem_password" that has
|
85
|
+
# access to /amqp_gem_testbed
|
86
|
+
context "when amqp_gem/amqp_gem_testbed has access to /amqp_gem_testbed" do
|
87
|
+
after :all do
|
88
|
+
done
|
89
|
+
end
|
90
|
+
|
91
|
+
context "and provided credentials are correct" do
|
92
|
+
it "succeeds" do
|
93
|
+
connection = AMQP.connect "amqp://amqp_gem:amqp_gem_password@localhost/amqp_gem_testbed"
|
94
|
+
|
95
|
+
done(0.3) {
|
96
|
+
connection.should be_connected
|
97
|
+
connection.close
|
98
|
+
}
|
99
|
+
end # it
|
100
|
+
end # context
|
101
|
+
|
102
|
+
context "and provided credentials ARE INCORRECT" do
|
103
|
+
it "succeeds" do
|
104
|
+
connection = AMQP.connect "amqp://amqp_gem:#{Time.now.to_i}@localhost/amqp_gem_testbed"
|
105
|
+
|
106
|
+
done(0.5) {
|
107
|
+
connection.should_not be_connected
|
108
|
+
connection.close
|
109
|
+
}
|
110
|
+
end # it
|
111
|
+
end # context
|
112
|
+
end # context
|
113
|
+
end # describe
|
114
|
+
end # describe "Authentication attempt"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
@@ -10,25 +10,30 @@ describe "Queue that was bound to default direct exchange thanks to Automatic Mo
|
|
10
10
|
|
11
11
|
include AMQP::Spec
|
12
12
|
|
13
|
-
default_timeout
|
13
|
+
default_timeout 2
|
14
14
|
|
15
15
|
amqp_before do
|
16
|
-
@channel =
|
16
|
+
@channel = AMQP::Channel.new
|
17
|
+
@channel.should be_open
|
17
18
|
|
18
19
|
@queue1 = @channel.queue("queue1")
|
19
20
|
@queue2 = @channel.queue("queue2")
|
20
21
|
|
21
22
|
# Rely on default direct exchange binding, see section 2.1.2.4 Automatic Mode in AMQP 0.9.1 spec.
|
22
|
-
@exchange =
|
23
|
+
@exchange = AMQP::Exchange.default(@channel)
|
23
24
|
end
|
24
25
|
|
25
26
|
|
27
|
+
default_options AMQP_OPTS
|
28
|
+
|
26
29
|
|
27
30
|
#
|
28
31
|
# Examples
|
29
32
|
#
|
30
33
|
|
31
34
|
it "receives messages with routing key equals it's name" do
|
35
|
+
@exchange.channel.should == @channel
|
36
|
+
|
32
37
|
number_of_received_messages = 0
|
33
38
|
expected_number_of_messages = 3
|
34
39
|
dispatched_data = "to be received by queue1"
|
@@ -36,14 +41,6 @@ describe "Queue that was bound to default direct exchange thanks to Automatic Mo
|
|
36
41
|
@queue1.subscribe do |payload|
|
37
42
|
number_of_received_messages += 1
|
38
43
|
payload.should == dispatched_data
|
39
|
-
|
40
|
-
if number_of_received_messages == expected_number_of_messages
|
41
|
-
$stdout.puts "Got all the messages I expected, wrapping up..."
|
42
|
-
done
|
43
|
-
else
|
44
|
-
n = expected_number_of_messages - number_of_received_messages
|
45
|
-
$stdout.puts "Still waiting for #{n} more message(s)"
|
46
|
-
end
|
47
44
|
end # subscribe
|
48
45
|
|
49
46
|
4.times do
|
@@ -57,5 +54,9 @@ describe "Queue that was bound to default direct exchange thanks to Automatic Mo
|
|
57
54
|
4.times do
|
58
55
|
@exchange.publish("some white noise", :routing_key => "killa key")
|
59
56
|
end
|
57
|
+
|
58
|
+
done(0.2) {
|
59
|
+
number_of_received_messages.should == expected_number_of_messages
|
60
|
+
}
|
60
61
|
end # it
|
61
62
|
end # describe
|
@@ -2,13 +2,13 @@
|
|
2
2
|
|
3
3
|
require "spec_helper"
|
4
4
|
|
5
|
-
describe
|
5
|
+
describe AMQP, "#close(&callback)" do
|
6
6
|
include AMQP::EMSpec
|
7
7
|
|
8
8
|
default_timeout 5
|
9
9
|
|
10
10
|
it "takes a callback which will run when we get back Channel.Close-Ok" do
|
11
|
-
|
11
|
+
AMQP::Channel.new.close do |amq|
|
12
12
|
done
|
13
13
|
end
|
14
14
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
describe
|
5
|
+
describe AMQP do
|
6
6
|
|
7
7
|
#
|
8
8
|
# Environment
|
@@ -13,7 +13,7 @@ describe MQ do
|
|
13
13
|
default_timeout 10
|
14
14
|
|
15
15
|
amqp_before do
|
16
|
-
@channel =
|
16
|
+
@channel = AMQP::Channel.new
|
17
17
|
end
|
18
18
|
|
19
19
|
|
@@ -156,7 +156,7 @@ describe MQ do
|
|
156
156
|
|
157
157
|
expect {
|
158
158
|
@channel.direct("previously.declared.durable.direct.exchange", :durable => false)
|
159
|
-
}.to raise_error(
|
159
|
+
}.to raise_error(AMQP::IncompatibleOptionsError)
|
160
160
|
|
161
161
|
done
|
162
162
|
end # it
|
@@ -275,7 +275,7 @@ describe MQ do
|
|
275
275
|
|
276
276
|
expect {
|
277
277
|
@channel.fanout("previously.declared.durable.topic.exchange", :durable => false)
|
278
|
-
}.to raise_error(
|
278
|
+
}.to raise_error(AMQP::IncompatibleOptionsError)
|
279
279
|
|
280
280
|
done
|
281
281
|
end # it
|
@@ -388,12 +388,19 @@ describe MQ do
|
|
388
388
|
|
389
389
|
|
390
390
|
context "when exchange is re-declared with parameters different from original declaration" do
|
391
|
-
|
392
|
-
|
391
|
+
amqp_after do
|
392
|
+
done
|
393
|
+
end
|
394
|
+
|
395
|
+
it "raises an exception" do
|
396
|
+
channel = AMQP::Channel.new
|
397
|
+
|
398
|
+
channel.topic("previously.declared.durable.topic.exchange", :durable => true)
|
399
|
+
channel.should be_open
|
393
400
|
|
394
401
|
expect {
|
395
|
-
|
396
|
-
}.to raise_error(
|
402
|
+
channel.topic("previously.declared.durable.topic.exchange", :durable => false)
|
403
|
+
}.to raise_error(AMQP::IncompatibleOptionsError)
|
397
404
|
|
398
405
|
done
|
399
406
|
end # it
|
@@ -417,9 +424,11 @@ describe MQ do
|
|
417
424
|
end # context
|
418
425
|
|
419
426
|
context "when exchange name is omitted" do
|
420
|
-
|
421
|
-
|
427
|
+
amqp_after do
|
428
|
+
done
|
429
|
+
end
|
422
430
|
|
431
|
+
it "uses amq.match" do
|
423
432
|
exchange = @channel.headers
|
424
433
|
exchange.name.should == "amq.match"
|
425
434
|
exchange.name.should_not == "amq.headers"
|
@@ -509,16 +518,19 @@ describe MQ do
|
|
509
518
|
|
510
519
|
|
511
520
|
context "when exchange is re-declared with parameters different from original declaration" do
|
512
|
-
|
513
|
-
|
521
|
+
amqp_after do
|
522
|
+
done
|
523
|
+
end
|
524
|
+
|
525
|
+
it "raises an exception" do
|
514
526
|
@channel.headers("previously.declared.durable.topic.exchange", :durable => true)
|
515
527
|
|
516
528
|
expect {
|
517
529
|
@channel.headers("previously.declared.durable.topic.exchange", :durable => false)
|
518
|
-
}.to raise_error(
|
530
|
+
}.to raise_error(AMQP::IncompatibleOptionsError)
|
519
531
|
|
520
532
|
done
|
521
533
|
end # it
|
522
534
|
end # context
|
523
535
|
end # describe
|
524
|
-
end # describe
|
536
|
+
end # describe AMQP
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
describe
|
5
|
+
describe AMQP do
|
6
6
|
|
7
7
|
#
|
8
8
|
# Environment
|
@@ -13,7 +13,7 @@ describe MQ do
|
|
13
13
|
default_timeout 5
|
14
14
|
|
15
15
|
amqp_before do
|
16
|
-
@channel =
|
16
|
+
@channel = AMQP::Channel.new
|
17
17
|
end
|
18
18
|
|
19
19
|
|
@@ -88,10 +88,10 @@ describe MQ do
|
|
88
88
|
|
89
89
|
expect {
|
90
90
|
@channel.queue("previously.declared.durable.queue", :durable => false)
|
91
|
-
}.to raise_error(
|
91
|
+
}.to raise_error(AMQP::IncompatibleOptionsError)
|
92
92
|
|
93
93
|
done
|
94
94
|
end # it
|
95
95
|
end # context
|
96
96
|
end # describe
|
97
|
-
end # describe
|
97
|
+
end # describe AMQP
|