bunny 0.1.1 → 0.2.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/README.markdown +15 -8
- data/examples/simple_consumer.rb +24 -5
- data/examples/{fanout.rb → simple_fanout.rb} +1 -6
- data/examples/simple_publisher.rb +1 -7
- data/examples/simple_topic.rb +59 -0
- data/lib/{amqp.rb → api_messages.rb} +1 -5
- data/lib/bunny.rb +21 -8
- data/lib/{amqp → bunny}/client.rb +16 -16
- data/lib/bunny/exchange.rb +16 -8
- data/lib/bunny/header.rb +1 -3
- data/lib/bunny/queue.rb +29 -20
- data/lib/{amqp → engineroom}/buffer.rb +6 -6
- data/lib/{amqp → engineroom}/frame.rb +4 -3
- data/lib/engineroom/protocol.rb +156 -0
- data/lib/engineroom/spec.rb +830 -0
- data/protocol/amqp-0.8.json +1 -1
- data/protocol/codegen.rb +83 -85
- data/spec/exchange_spec.rb +44 -2
- data/spec/queue_spec.rb +1 -1
- metadata +11 -12
- data/lib/amqp/protocol.rb +0 -158
- data/lib/amqp/spec.rb +0 -832
- data/protocol/amqp-0.8.xml +0 -3908
data/protocol/amqp-0.8.json
CHANGED
data/protocol/codegen.rb
CHANGED
@@ -18,13 +18,8 @@ puts ERB.new(%q[
|
|
18
18
|
#
|
19
19
|
# DO NOT EDIT! (edit protocol/codegen.rb instead, and run `rake codegen`)
|
20
20
|
|
21
|
-
module
|
22
|
-
|
23
|
-
VERSION_MAJOR = <%= s['major-version'] %>
|
24
|
-
VERSION_MINOR = <%= s['minor-version'] %>
|
25
|
-
PORT = <%= s['port'] %>
|
26
|
-
|
27
|
-
class Frame
|
21
|
+
module Transport
|
22
|
+
class Frame
|
28
23
|
def self.types
|
29
24
|
@types ||= {}
|
30
25
|
end
|
@@ -46,6 +41,13 @@ puts ERB.new(%q[
|
|
46
41
|
|
47
42
|
FOOTER = <%= frame_end = s['constants'].find{|c| c['name'] == 'FRAME-END' }['value'] %>
|
48
43
|
end
|
44
|
+
end
|
45
|
+
|
46
|
+
module Protocol
|
47
|
+
HEADER = <%= s['name'].dump %>.freeze
|
48
|
+
VERSION_MAJOR = <%= s['major-version'] %>
|
49
|
+
VERSION_MINOR = <%= s['minor-version'] %>
|
50
|
+
PORT = <%= s['port'] %>
|
49
51
|
|
50
52
|
RESPONSES = {
|
51
53
|
<%- s['constants'].select{|c| c['value'] != frame_end and (200..500).include? c['value'] }.each do |c| -%>
|
@@ -59,115 +61,111 @@ puts ERB.new(%q[
|
|
59
61
|
<%- end -%>
|
60
62
|
]
|
61
63
|
|
62
|
-
|
63
|
-
class
|
64
|
+
class Class
|
65
|
+
class << self
|
66
|
+
FIELDS.each do |f|
|
67
|
+
class_eval %[
|
68
|
+
def #{f} name
|
69
|
+
properties << [ :#{f}, name ] unless properties.include?([:#{f}, name])
|
70
|
+
attr_accessor name
|
71
|
+
end
|
72
|
+
]
|
73
|
+
end
|
74
|
+
|
75
|
+
def properties() @properties ||= [] end
|
76
|
+
|
77
|
+
def id() self::ID end
|
78
|
+
def name() self::NAME end
|
79
|
+
end
|
80
|
+
|
81
|
+
class Method
|
64
82
|
class << self
|
65
83
|
FIELDS.each do |f|
|
66
84
|
class_eval %[
|
67
85
|
def #{f} name
|
68
|
-
|
86
|
+
arguments << [ :#{f}, name ] unless arguments.include?([:#{f}, name])
|
69
87
|
attr_accessor name
|
70
88
|
end
|
71
89
|
]
|
72
90
|
end
|
73
91
|
|
74
|
-
def
|
92
|
+
def arguments() @arguments ||= [] end
|
75
93
|
|
76
|
-
def
|
77
|
-
def
|
94
|
+
def parent() Protocol.const_get(self.to_s[/Protocol::(.+?)::/,1]) end
|
95
|
+
def id() self::ID end
|
96
|
+
def name() self::NAME end
|
78
97
|
end
|
79
98
|
|
80
|
-
|
81
|
-
class
|
82
|
-
|
83
|
-
class_eval %[
|
84
|
-
def #{f} name
|
85
|
-
arguments << [ :#{f}, name ] unless arguments.include?([:#{f}, name])
|
86
|
-
attr_accessor name
|
87
|
-
end
|
88
|
-
]
|
89
|
-
end
|
90
|
-
|
91
|
-
def arguments() @arguments ||= [] end
|
92
|
-
|
93
|
-
def parent() Protocol.const_get(self.to_s[/Protocol::(.+?)::/,1]) end
|
94
|
-
def id() self::ID end
|
95
|
-
def name() self::NAME end
|
96
|
-
end
|
97
|
-
|
98
|
-
def == b
|
99
|
-
self.class.arguments.inject(true) do |eql, (type, name)|
|
100
|
-
eql and __send__("#{name}") == b.__send__("#{name}")
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def self.methods() @methods ||= {} end
|
106
|
-
|
107
|
-
def self.Method(id, name)
|
108
|
-
@_base_methods ||= {}
|
109
|
-
@_base_methods[id] ||= ::Class.new(Method) do
|
110
|
-
class_eval %[
|
111
|
-
def self.inherited klass
|
112
|
-
klass.const_set(:ID, #{id})
|
113
|
-
klass.const_set(:NAME, :#{name.to_s})
|
114
|
-
klass.parent.methods[#{id}] = klass
|
115
|
-
klass.parent.methods[klass::NAME] = klass
|
116
|
-
end
|
117
|
-
]
|
99
|
+
def == b
|
100
|
+
self.class.arguments.inject(true) do |eql, (type, name)|
|
101
|
+
eql and __send__("#{name}") == b.__send__("#{name}")
|
118
102
|
end
|
119
103
|
end
|
120
104
|
end
|
121
|
-
|
122
|
-
def self.
|
123
|
-
|
124
|
-
def self.
|
125
|
-
@
|
126
|
-
@
|
105
|
+
|
106
|
+
def self.methods() @methods ||= {} end
|
107
|
+
|
108
|
+
def self.Method(id, name)
|
109
|
+
@_base_methods ||= {}
|
110
|
+
@_base_methods[id] ||= ::Class.new(Method) do
|
127
111
|
class_eval %[
|
128
112
|
def self.inherited klass
|
129
113
|
klass.const_set(:ID, #{id})
|
130
114
|
klass.const_set(:NAME, :#{name.to_s})
|
131
|
-
|
132
|
-
|
115
|
+
klass.parent.methods[#{id}] = klass
|
116
|
+
klass.parent.methods[klass::NAME] = klass
|
133
117
|
end
|
134
118
|
]
|
135
119
|
end
|
136
120
|
end
|
137
121
|
end
|
122
|
+
|
123
|
+
def self.classes() @classes ||= {} end
|
124
|
+
|
125
|
+
def self.Class(id, name)
|
126
|
+
@_base_classes ||= {}
|
127
|
+
@_base_classes[id] ||= ::Class.new(Class) do
|
128
|
+
class_eval %[
|
129
|
+
def self.inherited klass
|
130
|
+
klass.const_set(:ID, #{id})
|
131
|
+
klass.const_set(:NAME, :#{name.to_s})
|
132
|
+
Protocol.classes[#{id}] = klass
|
133
|
+
Protocol.classes[klass::NAME] = klass
|
134
|
+
end
|
135
|
+
]
|
136
|
+
end
|
137
|
+
end
|
138
138
|
end
|
139
139
|
|
140
|
-
module
|
141
|
-
|
142
|
-
|
143
|
-
|
140
|
+
module Protocol
|
141
|
+
<%- s['classes'].each do |c| -%>
|
142
|
+
class <%= c['name'].capitalize.ljust(12) %> < Class( <%= c['id'].to_s.rjust(3) %>, :<%= c['name'].ljust(12) %> ); end
|
143
|
+
<%- end -%>
|
144
|
+
|
145
|
+
<%- s['classes'].each do |c| -%>
|
146
|
+
class <%= c['name'].capitalize %>
|
147
|
+
<%- c['properties'].each do |p| -%>
|
148
|
+
<%= p['type'].ljust(10) %> :<%= p['name'].tr('-','_') %>
|
149
|
+
<%- end if c['properties'] -%>
|
150
|
+
|
151
|
+
<%- c['methods'].each do |m| -%>
|
152
|
+
class <%= m['name'].capitalize.gsub(/-(.)/){ "#{$1.upcase}"}.ljust(12) %> < Method( <%= m['id'].to_s.rjust(3) %>, :<%= m['name'].tr('- ','_').ljust(14) %> ); end
|
144
153
|
<%- end -%>
|
145
154
|
|
146
|
-
<%-
|
147
|
-
class <%=
|
148
|
-
<%-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
class <%= m['name'].capitalize.gsub(/-(.)/){ "#{$1.upcase}"}.ljust(12) %> < Method( <%= m['id'].to_s.rjust(3) %>, :<%= m['name'].tr('- ','_').ljust(14) %> ); end
|
154
|
-
<%- end -%>
|
155
|
-
|
156
|
-
<%- c['methods'].each do |m| -%>
|
157
|
-
class <%= m['name'].capitalize.gsub(/-(.)/){ "#{$1.upcase}"} %>
|
158
|
-
<%- m['arguments'].each do |a| -%>
|
159
|
-
<%- if a['domain'] -%>
|
160
|
-
<%= s['domains'].find{|k,v| k == a['domain']}.last.ljust(10) %> :<%= a['name'].tr('- ','_') %>
|
161
|
-
<%- else -%>
|
162
|
-
<%= a['type'].ljust(10) %> :<%= a['name'].tr('- ','_') %>
|
163
|
-
<%- end -%>
|
164
|
-
<%- end if m['arguments'] -%>
|
165
|
-
end
|
166
|
-
|
155
|
+
<%- c['methods'].each do |m| -%>
|
156
|
+
class <%= m['name'].capitalize.gsub(/-(.)/){ "#{$1.upcase}"} %>
|
157
|
+
<%- m['arguments'].each do |a| -%>
|
158
|
+
<%- if a['domain'] -%>
|
159
|
+
<%= s['domains'].find{|k,v| k == a['domain']}.last.ljust(10) %> :<%= a['name'].tr('- ','_') %>
|
160
|
+
<%- else -%>
|
161
|
+
<%= a['type'].ljust(10) %> :<%= a['name'].tr('- ','_') %>
|
167
162
|
<%- end -%>
|
163
|
+
<%- end if m['arguments'] -%>
|
168
164
|
end
|
169
165
|
|
170
166
|
<%- end -%>
|
171
167
|
end
|
168
|
+
|
169
|
+
<%- end -%>
|
172
170
|
end
|
173
|
-
].gsub!(/^ /,''), nil, '>-%').result(binding)
|
171
|
+
].gsub!(/^ /,''), nil, '>-%').result(binding)
|
data/spec/exchange_spec.rb
CHANGED
@@ -16,10 +16,52 @@ describe Bunny::Exchange do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
it "should raise an error if instantiated as non-existent type" do
|
19
|
-
lambda { @b.exchange('bogus_ex', :type => :bogus) }.should raise_error(
|
19
|
+
lambda { @b.exchange('bogus_ex', :type => :bogus) }.should raise_error(API::ProtocolError)
|
20
20
|
end
|
21
21
|
|
22
|
-
it "should
|
22
|
+
it "should allow a default direct exchange to be instantiated by specifying :type" do
|
23
|
+
exch = @b.exchange('amq.direct', :type => :direct)
|
24
|
+
exch.should be_an_instance_of Bunny::Exchange
|
25
|
+
exch.name.should == 'amq.direct'
|
26
|
+
exch.type.should == :direct
|
27
|
+
@b.exchanges.has_key?('amq.direct').should be true
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should allow a default direct exchange to be instantiated without specifying :type" do
|
31
|
+
exch = @b.exchange('amq.direct')
|
32
|
+
exch.should be_an_instance_of Bunny::Exchange
|
33
|
+
exch.name.should == 'amq.direct'
|
34
|
+
exch.type.should == :direct
|
35
|
+
@b.exchanges.has_key?('amq.direct').should be true
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should allow a default fanout exchange to be instantiated without specifying :type" do
|
39
|
+
exch = @b.exchange('amq.fanout')
|
40
|
+
exch.should be_an_instance_of Bunny::Exchange
|
41
|
+
exch.name.should == 'amq.fanout'
|
42
|
+
exch.type.should == :fanout
|
43
|
+
@b.exchanges.has_key?('amq.fanout').should be true
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should allow a default topic exchange to be instantiated without specifying :type" do
|
47
|
+
exch = @b.exchange('amq.topic')
|
48
|
+
exch.should be_an_instance_of Bunny::Exchange
|
49
|
+
exch.name.should == 'amq.topic'
|
50
|
+
exch.type.should == :topic
|
51
|
+
@b.exchanges.has_key?('amq.topic').should be true
|
52
|
+
end
|
53
|
+
|
54
|
+
# headers exchange not implemented in RabbitMQ yet. Uncomment if target broker/server supports it
|
55
|
+
#
|
56
|
+
#it "should allow a default headers exchange to be instantiated without specifying :type" do
|
57
|
+
# exch = @b.exchange('amq.match')
|
58
|
+
# exch.should be_an_instance_of Bunny::Exchange
|
59
|
+
# exch.name.should == 'amq.match'
|
60
|
+
# exch.type.should == :headers
|
61
|
+
# @b.exchanges.has_key?('amq.match').should be true
|
62
|
+
#end
|
63
|
+
|
64
|
+
it "should create an exchange as direct by default" do
|
23
65
|
exch = @b.exchange('direct_defaultex')
|
24
66
|
exch.should be_an_instance_of Bunny::Exchange
|
25
67
|
exch.name.should == 'direct_defaultex'
|
data/spec/queue_spec.rb
CHANGED
@@ -53,7 +53,7 @@ describe Bunny::Queue do
|
|
53
53
|
q = @b.queue('test1')
|
54
54
|
msg = q.pop(:header => true)
|
55
55
|
msg.should be_an_instance_of Hash
|
56
|
-
msg[:header].should be_an_instance_of
|
56
|
+
msg[:header].should be_an_instance_of Protocol::Header
|
57
57
|
msg[:payload].should == 'This is a test message'
|
58
58
|
q.message_count.should == 0
|
59
59
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bunny
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Duncan
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-05-01 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -24,27 +24,26 @@ extra_rdoc_files: []
|
|
24
24
|
files:
|
25
25
|
- Rakefile
|
26
26
|
- README.markdown
|
27
|
-
- lib/
|
28
|
-
- lib/
|
29
|
-
- lib/
|
27
|
+
- lib/api_messages.rb
|
28
|
+
- lib/bunny.rb
|
29
|
+
- lib/engineroom/buffer.rb
|
30
|
+
- lib/engineroom/frame.rb
|
31
|
+
- lib/engineroom/protocol.rb
|
32
|
+
- lib/engineroom/spec.rb
|
30
33
|
- lib/bunny/exchange.rb
|
31
|
-
- lib/amqp/frame.rb
|
32
34
|
- lib/bunny/header.rb
|
33
|
-
- lib/amqp/protocol.rb
|
34
35
|
- lib/bunny/queue.rb
|
35
|
-
- lib/
|
36
|
-
- lib/amqp/spec.rb
|
37
|
-
- lib/bunny.rb
|
36
|
+
- lib/bunny/client.rb
|
38
37
|
- examples/simple.rb
|
39
|
-
- examples/
|
38
|
+
- examples/simple_fanout.rb
|
40
39
|
- examples/simple_consumer.rb
|
41
40
|
- examples/simple_publisher.rb
|
42
41
|
- examples/simple_ack.rb
|
42
|
+
- examples/simple_topic.rb
|
43
43
|
- spec/bunny_spec.rb
|
44
44
|
- spec/exchange_spec.rb
|
45
45
|
- spec/queue_spec.rb
|
46
46
|
- protocol/amqp-0.8.json
|
47
|
-
- protocol/amqp-0.8.xml
|
48
47
|
- protocol/codegen.rb
|
49
48
|
has_rdoc: true
|
50
49
|
homepage: http://github.com/celldee/bunny
|
data/lib/amqp/protocol.rb
DELETED
@@ -1,158 +0,0 @@
|
|
1
|
-
module AMQP
|
2
|
-
module Protocol
|
3
|
-
#:stopdoc:
|
4
|
-
class Class::Method
|
5
|
-
def initialize *args
|
6
|
-
opts = args.pop if args.last.is_a? Hash
|
7
|
-
opts ||= {}
|
8
|
-
|
9
|
-
@debug = 1 # XXX hack, p(obj) == '' if no instance vars are set
|
10
|
-
|
11
|
-
if args.size == 1 and args.first.is_a? Buffer
|
12
|
-
buf = args.shift
|
13
|
-
else
|
14
|
-
buf = nil
|
15
|
-
end
|
16
|
-
|
17
|
-
self.class.arguments.each do |type, name|
|
18
|
-
val = buf ? buf.read(type) :
|
19
|
-
args.shift || opts[name] || opts[name.to_s]
|
20
|
-
instance_variable_set("@#{name}", val)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def arguments
|
25
|
-
self.class.arguments.inject({}) do |hash, (type, name)|
|
26
|
-
hash.update name => instance_variable_get("@#{name}")
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def to_binary
|
31
|
-
buf = Buffer.new
|
32
|
-
buf.write :short, self.class.parent.id
|
33
|
-
buf.write :short, self.class.id
|
34
|
-
|
35
|
-
bits = []
|
36
|
-
|
37
|
-
self.class.arguments.each do |type, name|
|
38
|
-
val = instance_variable_get("@#{name}")
|
39
|
-
if type == :bit
|
40
|
-
bits << (val || false)
|
41
|
-
else
|
42
|
-
unless bits.empty?
|
43
|
-
buf.write :bit, bits
|
44
|
-
bits = []
|
45
|
-
end
|
46
|
-
buf.write type, val
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
buf.write :bit, bits unless bits.empty?
|
51
|
-
buf.rewind
|
52
|
-
|
53
|
-
buf
|
54
|
-
end
|
55
|
-
|
56
|
-
def to_s
|
57
|
-
to_binary.to_s
|
58
|
-
end
|
59
|
-
|
60
|
-
def to_frame channel = 0
|
61
|
-
Frame::Method.new(self, channel)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
#:startdoc:
|
66
|
-
#
|
67
|
-
# Contains a properties hash that holds some potentially interesting
|
68
|
-
# information.
|
69
|
-
# * :delivery_mode
|
70
|
-
# 1 equals transient.
|
71
|
-
# 2 equals persistent. Unconsumed persistent messages will survive
|
72
|
-
# a server restart when they are stored in a durable queue.
|
73
|
-
# * :redelivered
|
74
|
-
# True or False
|
75
|
-
# * :routing_key
|
76
|
-
# The routing string used for matching this message to this queue.
|
77
|
-
# * :priority
|
78
|
-
# An integer in the range of 0 to 9 inclusive.
|
79
|
-
# * :content_type
|
80
|
-
# Always "application/octet-stream" (byte stream)
|
81
|
-
# * :exchange
|
82
|
-
# The source exchange which published this message.
|
83
|
-
# * :message_count
|
84
|
-
# The number of unconsumed messages contained in the queue.
|
85
|
-
# * :delivery_tag
|
86
|
-
# A monotonically increasing integer. This number should not be trusted
|
87
|
-
# as a sequence number. There is no guarantee it won't get reset.
|
88
|
-
class Header
|
89
|
-
def initialize *args
|
90
|
-
opts = args.pop if args.last.is_a? Hash
|
91
|
-
opts ||= {}
|
92
|
-
|
93
|
-
first = args.shift
|
94
|
-
|
95
|
-
if first.is_a? ::Class and first.ancestors.include? Protocol::Class
|
96
|
-
@klass = first
|
97
|
-
@size = args.shift || 0
|
98
|
-
@weight = args.shift || 0
|
99
|
-
@properties = opts
|
100
|
-
|
101
|
-
elsif first.is_a? Buffer or first.is_a? String
|
102
|
-
buf = first
|
103
|
-
buf = Buffer.new(buf) unless buf.is_a? Buffer
|
104
|
-
|
105
|
-
@klass = Protocol.classes[buf.read(:short)]
|
106
|
-
@weight = buf.read(:short)
|
107
|
-
@size = buf.read(:longlong)
|
108
|
-
|
109
|
-
props = buf.read(:properties, *klass.properties.map{|type,_| type })
|
110
|
-
@properties = Hash[*klass.properties.map{|_,name| name }.zip(props).reject{|k,v| v.nil? }.flatten]
|
111
|
-
|
112
|
-
else
|
113
|
-
raise ArgumentError, 'Invalid argument'
|
114
|
-
end
|
115
|
-
|
116
|
-
end
|
117
|
-
attr_accessor :klass, :size, :weight, :properties
|
118
|
-
|
119
|
-
def to_binary
|
120
|
-
buf = Buffer.new
|
121
|
-
buf.write :short, klass.id
|
122
|
-
buf.write :short, weight # XXX rabbitmq only supports weight == 0
|
123
|
-
buf.write :longlong, size
|
124
|
-
buf.write :properties, (klass.properties.map do |type, name|
|
125
|
-
[ type, properties[name] || properties[name.to_s] ]
|
126
|
-
end)
|
127
|
-
buf.rewind
|
128
|
-
buf
|
129
|
-
end
|
130
|
-
|
131
|
-
def to_s
|
132
|
-
to_binary.to_s
|
133
|
-
end
|
134
|
-
|
135
|
-
def to_frame channel = 0
|
136
|
-
Frame::Header.new(self, channel)
|
137
|
-
end
|
138
|
-
|
139
|
-
def == header
|
140
|
-
[ :klass, :size, :weight, :properties ].inject(true) do |eql, field|
|
141
|
-
eql and __send__(field) == header.__send__(field)
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
def method_missing meth, *args, &blk
|
146
|
-
@properties.has_key?(meth) || @klass.properties.find{|_,name| name == meth } ? @properties[meth] :
|
147
|
-
super
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
def self.parse buf
|
152
|
-
buf = Buffer.new(buf) unless buf.is_a? Buffer
|
153
|
-
class_id, method_id = buf.read(:short, :short)
|
154
|
-
classes[class_id].methods[method_id].new(buf)
|
155
|
-
end
|
156
|
-
#:stopdoc:
|
157
|
-
end
|
158
|
-
end
|