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.
Files changed (109) hide show
  1. data/.gitignore +3 -4
  2. data/.travis.yml +3 -5
  3. data/.yardopts +6 -0
  4. data/CHANGELOG +26 -7
  5. data/Gemfile +15 -7
  6. data/README.textile +216 -0
  7. data/Rakefile +0 -6
  8. data/amqp.gemspec +14 -4
  9. data/bin/jenkins.sh +27 -0
  10. data/bin/set_test_suite_realms_up.sh +16 -2
  11. data/docs/VendorSpecificExtensions.textile +32 -0
  12. data/examples/extensions/rabbitmq/publisher_confirmations_with_transient_messages.rb +53 -0
  13. data/examples/hello_world.rb +29 -0
  14. data/examples/real-world/task-queue/README.textile +3 -0
  15. data/examples/real-world/task-queue/consumer.rb +27 -0
  16. data/examples/real-world/task-queue/producer.rb +22 -0
  17. data/examples/various/ack.rb +70 -0
  18. data/examples/various/automatic_binding_for_default_direct_exchange.rb +53 -0
  19. data/examples/various/basic_get.rb +65 -0
  20. data/examples/various/callbacks.rb +45 -0
  21. data/examples/various/clock.rb +74 -0
  22. data/examples/various/declare_a_queue_without_assignment.rb +46 -0
  23. data/examples/various/declare_an_exchange_without_assignment.rb +46 -0
  24. data/examples/various/hashtable.rb +60 -0
  25. data/examples/{logger.rb → various/logger.rb} +9 -7
  26. data/examples/{multiclock.rb → various/multiclock.rb} +15 -17
  27. data/examples/various/open_channel_without_assignment.rb +34 -0
  28. data/examples/various/pingpong.rb +53 -0
  29. data/examples/various/primes-simple.rb +29 -0
  30. data/examples/various/primes.rb +76 -0
  31. data/examples/various/pubsub.rb +43 -0
  32. data/examples/various/queue_status.rb +58 -0
  33. data/examples/various/stocks.rb +59 -0
  34. data/examples/various/weather_updates.rb +63 -0
  35. data/lib/amqp.rb +11 -2
  36. data/lib/amqp/basic_client.rb +23 -54
  37. data/lib/amqp/channel.rb +577 -805
  38. data/lib/amqp/client.rb +37 -275
  39. data/lib/amqp/connection.rb +165 -93
  40. data/lib/amqp/deprecated/fork.rb +15 -0
  41. data/lib/amqp/deprecated/logger.rb +99 -0
  42. data/lib/amqp/deprecated/mq.rb +20 -0
  43. data/lib/amqp/deprecated/rpc.rb +168 -0
  44. data/lib/amqp/exchange.rb +409 -281
  45. data/lib/amqp/extensions/rabbitmq.rb +1 -0
  46. data/lib/amqp/header.rb +41 -17
  47. data/lib/amqp/logger.rb +10 -84
  48. data/lib/amqp/queue.rb +457 -320
  49. data/lib/amqp/rpc.rb +11 -107
  50. data/lib/amqp/version.rb +1 -1
  51. data/lib/mq.rb +2 -1
  52. data/lib/mq/logger.rb +2 -0
  53. data/lib/mq/rpc.rb +2 -0
  54. data/spec/integration/authentication_spec.rb +36 -40
  55. data/spec/integration/automatic_binding_for_default_direct_exchange_spec.rb +3 -5
  56. data/spec/integration/basic_get_spec.rb +91 -0
  57. data/spec/integration/channel_close_spec.rb +5 -5
  58. data/spec/integration/exchange_declaration_spec.rb +6 -53
  59. data/spec/integration/extensions/basic_return_spec.rb +47 -0
  60. data/spec/integration/queue_declaration_spec.rb +14 -17
  61. data/spec/integration/queue_exclusivity_spec.rb +49 -48
  62. data/spec/integration/reply_queue_communication_spec.rb +6 -4
  63. data/spec/integration/store_and_forward_spec.rb +9 -36
  64. data/spec/integration/topic_subscription_spec.rb +1 -1
  65. data/spec/integration/workload_distribution_spec.rb +1 -0
  66. data/spec/spec_helper.rb +69 -43
  67. data/spec/unit/amqp/connection_spec.rb +27 -23
  68. data/tasks.rb +11 -0
  69. metadata +124 -95
  70. data/README.md +0 -156
  71. data/TODO +0 -30
  72. data/amqp.pre.gemspec +0 -6
  73. data/examples/ack.rb +0 -47
  74. data/examples/automatic_binding_for_default_direct_exchange.rb +0 -65
  75. data/examples/callbacks.rb +0 -40
  76. data/examples/clock.rb +0 -65
  77. data/examples/default_channel.rb +0 -19
  78. data/examples/hashtable.rb +0 -61
  79. data/examples/immediately_bind_a_server_named_queue.rb +0 -38
  80. data/examples/internal.rb +0 -51
  81. data/examples/issues/issue_75.rb +0 -21
  82. data/examples/issues/issue_94.rb +0 -23
  83. data/examples/pingpong.rb +0 -54
  84. data/examples/pop.rb +0 -45
  85. data/examples/primes-simple.rb +0 -21
  86. data/examples/primes.rb +0 -101
  87. data/examples/simple.rb +0 -81
  88. data/examples/stocks.rb +0 -67
  89. data/gemfiles/eventmachine-pre +0 -24
  90. data/lib/amqp/buffer.rb +0 -272
  91. data/lib/amqp/collection.rb +0 -60
  92. data/lib/amqp/frame.rb +0 -68
  93. data/lib/amqp/protocol.rb +0 -163
  94. data/lib/amqp/server.rb +0 -101
  95. data/lib/amqp/spec.rb +0 -832
  96. data/protocol/amqp-0.8.json +0 -617
  97. data/protocol/amqp-0.8.xml +0 -3908
  98. data/protocol/codegen.rb +0 -175
  99. data/protocol/doc.txt +0 -281
  100. data/research/api.rb +0 -52
  101. data/research/primes-forked.rb +0 -65
  102. data/research/primes-processes.rb +0 -137
  103. data/research/primes-threaded.rb +0 -51
  104. data/spec/integration/queue_status_spec.rb +0 -44
  105. data/spec/unit/amqp/buffer_spec.rb +0 -178
  106. data/spec/unit/amqp/client_spec.rb +0 -102
  107. data/spec/unit/amqp/collection_spec.rb +0 -144
  108. data/spec/unit/amqp/frame_spec.rb +0 -60
  109. data/spec/unit/amqp/protocol_spec.rb +0 -51
@@ -1,52 +0,0 @@
1
- # encoding: utf-8
2
-
3
- $:.unshift File.dirname(__FILE__) + '/../lib'
4
- require 'rubygems'
5
- require 'amqp'
6
-
7
- # AMQP.start do |amqp|
8
- # amqp.channel!(1)
9
- #
10
- # q = amqp.queue.declare(:queue => 'test',
11
- # :exclusive => false,
12
- # :auto_delete => true)
13
- #
14
- # q.bind(:exchange => '',
15
- # :routing_key => 'test_route')
16
- #
17
- # amqp.basic.consume(:queue => q,
18
- # :no_local => false,
19
- # :no_ack => true) { |header, body|
20
- # p ['got', header, body]
21
- # }
22
- # end
23
-
24
- AMQP.start do |amqp|
25
- amqp.exchange('my_exchange', :topic) do |e|
26
- e.publish(routing_key, data, :header => 'blah')
27
- end
28
-
29
- amqp.queue('my_queue').subscribe do |header, body|
30
- p ['got', header, body]
31
- end
32
- end
33
-
34
- def AMQP::Channel.method_missing meth, *args, &blk
35
- (Thread.current[:mq] ||= AMQP::Channel.new).__send__(meth, *args, &blk)
36
- end
37
-
38
- mq = AMQP::Channel.new
39
- mq.direct.publish('alkjsdf', :key => 'name')
40
- mq.topic # 'amq.topic'
41
- mq.topic('test').publish('some data', :key => 'stock.usd.*')
42
-
43
- # amq.queue('user1').bind(amq.topic('conversation.1'))
44
-
45
- mq.queue('abc').get {}
46
- mq.queue('abc').peek {}
47
- mq.queue('abc').subscribe { |body|
48
-
49
- }
50
-
51
- mq.queue('abc').bind(:exchange => mq.topic, :routing_key => 'abc', :nowait => true, :arguments => {})
52
-
@@ -1,65 +0,0 @@
1
- # encoding: utf-8
2
-
3
- $:.unshift File.dirname(__FILE__) + '/../lib'
4
- require 'mq'
5
-
6
- MAX = 5000
7
-
8
- def EM.fork &blk
9
- raise if reactor_running?
10
-
11
- unless @forks
12
- at_exit {
13
- @forks.each { |pid| Process.kill('KILL', pid) }
14
- }
15
- end
16
-
17
- (@forks ||= []) << Kernel.fork do
18
- EM.run(&blk)
19
- end
20
- end
21
-
22
- def log(*args)
23
- p args
24
- end
25
-
26
- # AMQP::Channel.logging = true
27
-
28
- # worker
29
-
30
- workers = ARGV[0] ? (Integer(ARGV[0]) rescue 2) : 2
31
-
32
- workers.times do
33
- EM.fork {
34
- log "prime checker", Process.pid, :started
35
-
36
- class Fixnum
37
- def prime?
38
- ('1' * self) !~ /^1?$|^(11+?)\1+$/
39
- end
40
- end
41
-
42
- AMQP::Channel.queue('prime checker').subscribe { |info, num|
43
- log "prime checker #{Process.pid}", :prime?, num
44
- if Integer(num).prime?
45
- AMQP::Channel.queue(info.reply_to).publish(num, :reply_to => Process.pid)
46
- end
47
- }
48
- }
49
- end
50
-
51
- # controller
52
-
53
- EM.run {
54
- AMQP::Channel.queue('prime collector').subscribe { |info, prime|
55
- log 'prime collector', :received, prime, :from, info.reply_to
56
- (@primes ||= []) << Integer(prime)
57
- EM.stop_event_loop if prime == '499'
58
- }
59
-
60
- MAX.times do |i|
61
- EM.next_tick do
62
- AMQP::Channel.queue('prime checker').publish((i+1).to_s, :reply_to => 'prime collector')
63
- end
64
- end
65
- }
@@ -1,137 +0,0 @@
1
- # encoding: utf-8
2
-
3
- $:.unshift File.dirname(__FILE__) + '/../lib'
4
- require 'mq'
5
-
6
- MAX = 500
7
-
8
- EM.run {
9
-
10
- def log(*args)
11
- p args
12
- end
13
-
14
- # AMQP::Channel.logging = true
15
-
16
- if ARGV[0] == 'worker'
17
-
18
- log "prime checker #{Process.pid}", :started
19
-
20
- class Fixnum
21
- def prime?
22
- ('1' * self) !~ /^1?$|^(11+?)\1+$/
23
- end
24
- end
25
-
26
- AMQP::Channel.queue('prime checker').subscribe { |info, num|
27
- log "prime checker #{Process.pid}", :prime?, num
28
- if Integer(num).prime?
29
- AMQP::Channel.queue(info.reply_to).publish(num, :reply_to => Process.pid)
30
- EM.stop_event_loop if num == (MAX-1).to_s
31
- end
32
- }
33
-
34
- elsif ARGV[0] == 'controller'
35
-
36
- AMQP::Channel.queue('prime collector').subscribe { |info, prime|
37
- log 'prime collector', :received, prime, :from, info.reply_to
38
- (@primes ||= []) << Integer(prime)
39
- }
40
-
41
- MAX.times do |i|
42
- EM.next_tick do
43
- AMQP::Channel.queue('prime checker').publish((i+1).to_s, :reply_to => 'prime collector')
44
- end
45
- end
46
-
47
- else # run n workers and 1 controller as an example
48
-
49
- workers = ARGV[0] ? (Integer(ARGV[0]) rescue 2) : 2
50
-
51
- ([ :worker ] * workers + [ :controller ]).each do |type|
52
- log :spawning, "`ruby #{$0} #{type}`"
53
-
54
- EM.popen("ruby #{$0} #{type}") do |c|
55
- def c.receive_data data
56
- puts data
57
- end
58
-
59
- def c.unbind
60
- EM.stop_event_loop
61
- end
62
- end
63
- end
64
-
65
- end
66
- }
67
-
68
- __END__
69
-
70
- ["prime checker", :started, {:pid => 1958}]
71
- ["prime checker", :started, {:pid => 1957}]
72
- ["prime checker", :started, {:pid => 1956}]
73
- ["prime checker", :prime?, "1", {:pid => 1958}]
74
- ["prime checker", :prime?, "2", {:pid => 1957}]
75
- ["prime collector", :received, "2", {:from_pid => "1957"}]
76
- ["prime checker", :prime?, "3", {:pid => 1956}]
77
- ["prime collector", :received, "3", {:from_pid => "1956"}]
78
- ["prime checker", :prime?, "4", {:pid => 1958}]
79
- ["prime checker", :prime?, "5", {:pid => 1957}]
80
- ["prime collector", :received, "5", {:from_pid => "1957"}]
81
- ["prime checker", :prime?, "6", {:pid => 1956}]
82
- ["prime checker", :prime?, "7", {:pid => 1958}]
83
- ["prime collector", :received, "7", {:from_pid => "1958"}]
84
- ["prime checker", :prime?, "8", {:pid => 1957}]
85
- ["prime checker", :prime?, "9", {:pid => 1956}]
86
- ["prime checker", :prime?, "10", {:pid => 1958}]
87
- ["prime checker", :prime?, "11", {:pid => 1957}]
88
- ["prime collector", :received, "11", {:from_pid => "1957"}]
89
- ["prime checker", :prime?, "12", {:pid => 1956}]
90
- ["prime checker", :prime?, "13", {:pid => 1958}]
91
- ["prime collector", :received, "13", {:from_pid => "1958"}]
92
- ["prime checker", :prime?, "14", {:pid => 1957}]
93
- ["prime checker", :prime?, "15", {:pid => 1956}]
94
- ["prime checker", :prime?, "16", {:pid => 1958}]
95
- ["prime checker", :prime?, "17", {:pid => 1957}]
96
- ["prime collector", :received, "17", {:from_pid => "1957"}]
97
- ["prime checker", :prime?, "18", {:pid => 1956}]
98
- ["prime checker", :prime?, "19", {:pid => 1958}]
99
- ["prime collector", :received, "19", {:from_pid => "1958"}]
100
- ["prime checker", :prime?, "20", {:pid => 1957}]
101
- ["prime checker", :prime?, "21", {:pid => 1956}]
102
- ["prime checker", :prime?, "22", {:pid => 1958}]
103
- ["prime checker", :prime?, "23", {:pid => 1957}]
104
- ["prime collector", :received, "23", {:from_pid => "1957"}]
105
- ["prime checker", :prime?, "24", {:pid => 1956}]
106
- ["prime checker", :prime?, "25", {:pid => 1958}]
107
- ["prime checker", :prime?, "26", {:pid => 1957}]
108
- ["prime checker", :prime?, "27", {:pid => 1956}]
109
- ["prime checker", :prime?, "28", {:pid => 1958}]
110
- ["prime checker", :prime?, "29", {:pid => 1957}]
111
- ["prime collector", :received, "29", {:from_pid => "1957"}]
112
- ["prime checker", :prime?, "30", {:pid => 1956}]
113
- ["prime checker", :prime?, "31", {:pid => 1958}]
114
- ["prime collector", :received, "31", {:from_pid => "1958"}]
115
- ["prime checker", :prime?, "32", {:pid => 1957}]
116
- ["prime checker", :prime?, "33", {:pid => 1956}]
117
- ["prime checker", :prime?, "34", {:pid => 1958}]
118
- ["prime checker", :prime?, "35", {:pid => 1957}]
119
- ["prime checker", :prime?, "36", {:pid => 1956}]
120
- ["prime checker", :prime?, "37", {:pid => 1958}]
121
- ["prime collector", :received, "37", {:from_pid => "1958"}]
122
- ["prime checker", :prime?, "38", {:pid => 1957}]
123
- ["prime checker", :prime?, "39", {:pid => 1956}]
124
- ["prime checker", :prime?, "40", {:pid => 1958}]
125
- ["prime checker", :prime?, "41", {:pid => 1957}]
126
- ["prime collector", :received, "41", {:from_pid => "1957"}]
127
- ["prime checker", :prime?, "42", {:pid => 1956}]
128
- ["prime checker", :prime?, "43", {:pid => 1958}]
129
- ["prime collector", :received, "43", {:from_pid => "1958"}]
130
- ["prime checker", :prime?, "44", {:pid => 1957}]
131
- ["prime checker", :prime?, "45", {:pid => 1956}]
132
- ["prime checker", :prime?, "46", {:pid => 1958}]
133
- ["prime checker", :prime?, "47", {:pid => 1957}]
134
- ["prime collector", :received, "47", {:from_pid => "1957"}]
135
- ["prime checker", :prime?, "48", {:pid => 1956}]
136
- ["prime checker", :prime?, "49", {:pid => 1958}]
137
- ["prime checker", :prime?, "50", {:pid => 1957}]
@@ -1,51 +0,0 @@
1
- # encoding: utf-8
2
-
3
- $:.unshift File.dirname(__FILE__) + '/../lib'
4
- require 'mq'
5
-
6
- MAX = 500
7
-
8
- def log(*args)
9
- p args
10
- end
11
-
12
- # AMQP::Channel.logging = true
13
-
14
- EM.run {
15
-
16
- # worker
17
-
18
- log "prime checker", Process.pid, :started
19
-
20
- class Fixnum
21
- def prime?
22
- ('1' * self) !~ /^1?$|^(11+?)\1+$/
23
- end
24
- end
25
-
26
- AMQP::Channel.queue('prime checker').subscribe { |info, num|
27
- EM.defer(proc {
28
-
29
- log "prime checker #{Process.pid}-#{Thread.current.object_id}", :prime?, num
30
- if Integer(num).prime?
31
- AMQP::Channel.queue(info.reply_to).publish(num, :reply_to => "#{Process.pid}-#{Thread.current.object_id}")
32
- EM.stop_event_loop if num == '499'
33
- end
34
-
35
- })
36
- }
37
-
38
- # controller
39
-
40
- AMQP::Channel.queue('prime collector').subscribe { |info, prime|
41
- log 'prime collector', :received, prime, :from, info.reply_to
42
- (@primes ||= []) << Integer(prime)
43
- }
44
-
45
- MAX.times do |i|
46
- EM.next_tick do
47
- AMQP::Channel.queue('prime checker').publish((i+1).to_s, :reply_to => 'prime collector')
48
- end
49
- end
50
-
51
- }
@@ -1,44 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'spec_helper'
4
-
5
- describe AMQP::Queue do
6
-
7
- #
8
- # Environment
9
- #
10
-
11
- include EventedSpec::AMQPSpec
12
-
13
- default_timeout 5
14
-
15
-
16
-
17
- #
18
- # Examples
19
- #
20
-
21
- describe "#status" do
22
- it "yields # of messages & consumers to the callback" do
23
- events = []
24
- channel = AMQP::Channel.new
25
-
26
- queue1 = channel.queue("", :auto_delete => true)
27
- queue2 = channel.queue("amqpgem.tests.a.named.queue", :auto_delete => true)
28
-
29
- EventMachine.add_timer(1.0) do
30
- queue1.status do |m, c|
31
- events << :queue1_declare_ok
32
- end
33
- queue2.status do |m, c|
34
- events << :queue2_declare_ok
35
- end
36
- end
37
-
38
- done(2.0) {
39
- events.should include(:queue1_declare_ok)
40
- events.should include(:queue2_declare_ok)
41
- }
42
- end
43
- end
44
- end
@@ -1,178 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require "spec_helper"
4
- require "amqp/buffer"
5
-
6
-
7
- if [].map.respond_to? :with_index
8
- class Array #:nodoc:
9
- def enum_with_index
10
- each.with_index
11
- end
12
- end
13
- else
14
- require 'enumerator'
15
- end
16
-
17
-
18
- describe AMQP::Buffer do
19
-
20
- #
21
- # Examples
22
- #
23
-
24
- it "has contents" do
25
- subject.contents.should == ""
26
- end
27
-
28
- it "can be initialized with data" do
29
- @buffer = described_class.new("abc")
30
- @buffer.contents.should == "abc"
31
- end
32
-
33
- it "can append strings" do
34
- subject << "abc"
35
- subject << "def"
36
-
37
- subject.contents.should == "abcdef"
38
- end
39
-
40
- it "can append other buffers" do
41
- subject << described_class.new("abc")
42
-
43
- subject.data.should == "abc"
44
- end
45
-
46
- it "has current position" do
47
- subject.pos.should == 0
48
-
49
- subject << described_class.new("abc")
50
-
51
- subject.pos.should == 0
52
- end
53
-
54
-
55
- it "has length" do
56
- subject.length.should == 0
57
-
58
- subject << "abc"
59
-
60
- subject.length.should == 3
61
- # check for a crazy case when both RSpec and Bacon are loaded;
62
- # then == matcher ALWAYS PASSES. Le sigh.
63
- subject.length.should_not == 300
64
- end
65
-
66
-
67
- it "provides emptiness predicate" do
68
- subject.should be_empty
69
- subject << "xyz"
70
-
71
- subject.should_not be_empty
72
- end
73
-
74
-
75
- it "supports writing of data" do
76
- subject._write("abc")
77
- subject.pos.should == 3
78
- subject.rewind
79
- subject.pos.should == 0
80
- end
81
-
82
-
83
- it "supports reading of data" do
84
- subject._write("abc")
85
- subject.rewind
86
-
87
- subject._read(2).should == "ab"
88
- subject.pos.should == 0
89
- subject._read(1).should == "c"
90
- subject.pos.should == 0
91
- end
92
-
93
-
94
- it "raises on overflow" do
95
- expect {
96
- subject._read(1)
97
- }.should raise_error(described_class::Overflow)
98
- end
99
-
100
-
101
- it "refuses reading of unsupported types" do
102
- expect {
103
- subject.read(:junk)
104
- }.to raise_error(described_class::InvalidType)
105
- end
106
-
107
-
108
- it "refuses writing of unsupported types" do
109
- expect {
110
- subject.write(:junk, 1)
111
- }.to raise_error(described_class::InvalidType)
112
- end
113
-
114
-
115
- { :octet => 0b10101010,
116
- :short => 100,
117
- :long => 100_000_000,
118
- :longlong => 666_555_444_333_222_111,
119
- :shortstr => 'hello',
120
- :longstr => 'bye'*500,
121
- :timestamp => time = Time.at(Time.now.to_i),
122
- :table => { :this => 'is', :a => 'hash', :with => {:nested => 123, :and => time, :also => 123.456} },
123
- :bit => true
124
- }.each do |type, value|
125
- it "can read and write a #{type}" do
126
- subject.write(type, value)
127
- subject.rewind
128
-
129
- subject.read(type).should == value
130
- subject.should be_empty
131
- end # it
132
- end # each
133
-
134
-
135
- it 'can read and write multiple bits' do
136
- bits = [true, false, false, true, true, false, false, true, true, false]
137
- subject.write(:bit, bits)
138
- subject.write(:octet, 100)
139
-
140
- subject.rewind
141
-
142
- bits.map do
143
- subject.read(:bit)
144
- end.should == bits
145
- subject.read(:octet).should == 100
146
- end
147
-
148
- it 'can read and write property tables' do
149
- properties = ([
150
- [:octet, 1],
151
- [:shortstr, 'abc'],
152
- [:bit, true],
153
- [:bit, false],
154
- [:shortstr, nil],
155
- [:timestamp, nil],
156
- [:table, { :a => 'hash' }],
157
- ]*5).sort_by {rand}
158
-
159
- subject.write(:properties, properties)
160
- subject.rewind
161
- subject.read(:properties, *properties.map { |type, _| type }).should == properties.map { |_, value| value }
162
- subject.should be_empty
163
- end
164
-
165
- it 'does transactional reads with #extract' do
166
- subject.write :octet, 8
167
- orig = subject.to_s
168
-
169
- subject.rewind
170
- subject.extract do |b|
171
- b.read :octet
172
- b.read :short
173
- end
174
-
175
- subject.pos.should == 0
176
- subject.data.should == orig
177
- end
178
- end # describe