sparqcode_bunny 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/.gitignore +10 -0
  2. data/.rspec +3 -0
  3. data/.travis.yml +15 -0
  4. data/.yardopts +9 -0
  5. data/CHANGELOG +27 -0
  6. data/Gemfile +39 -0
  7. data/LICENSE +21 -0
  8. data/README.textile +82 -0
  9. data/Rakefile +14 -0
  10. data/bunny.gemspec +43 -0
  11. data/examples/simple_08.rb +32 -0
  12. data/examples/simple_09.rb +32 -0
  13. data/examples/simple_ack_08.rb +35 -0
  14. data/examples/simple_ack_09.rb +35 -0
  15. data/examples/simple_consumer_08.rb +55 -0
  16. data/examples/simple_consumer_09.rb +55 -0
  17. data/examples/simple_fanout_08.rb +41 -0
  18. data/examples/simple_fanout_09.rb +41 -0
  19. data/examples/simple_headers_08.rb +42 -0
  20. data/examples/simple_headers_09.rb +42 -0
  21. data/examples/simple_publisher_08.rb +29 -0
  22. data/examples/simple_publisher_09.rb +29 -0
  23. data/examples/simple_topic_08.rb +61 -0
  24. data/examples/simple_topic_09.rb +61 -0
  25. data/ext/amqp-0.8.json +616 -0
  26. data/ext/amqp-0.9.1.json +388 -0
  27. data/ext/config.yml +4 -0
  28. data/ext/qparser.rb +469 -0
  29. data/lib/bunny/channel08.rb +39 -0
  30. data/lib/bunny/channel09.rb +39 -0
  31. data/lib/bunny/client08.rb +472 -0
  32. data/lib/bunny/client09.rb +374 -0
  33. data/lib/bunny/consumer.rb +35 -0
  34. data/lib/bunny/exchange08.rb +171 -0
  35. data/lib/bunny/exchange09.rb +159 -0
  36. data/lib/bunny/queue08.rb +403 -0
  37. data/lib/bunny/queue09.rb +325 -0
  38. data/lib/bunny/subscription08.rb +87 -0
  39. data/lib/bunny/subscription09.rb +87 -0
  40. data/lib/bunny/system_timer.rb +14 -0
  41. data/lib/bunny/version.rb +5 -0
  42. data/lib/bunny.rb +109 -0
  43. data/lib/qrack/amq-client-url.rb +165 -0
  44. data/lib/qrack/channel.rb +20 -0
  45. data/lib/qrack/client.rb +235 -0
  46. data/lib/qrack/errors.rb +5 -0
  47. data/lib/qrack/protocol/protocol08.rb +134 -0
  48. data/lib/qrack/protocol/protocol09.rb +135 -0
  49. data/lib/qrack/protocol/spec08.rb +828 -0
  50. data/lib/qrack/protocol/spec09.rb +524 -0
  51. data/lib/qrack/qrack08.rb +20 -0
  52. data/lib/qrack/qrack09.rb +20 -0
  53. data/lib/qrack/queue.rb +40 -0
  54. data/lib/qrack/subscription.rb +112 -0
  55. data/lib/qrack/transport/buffer08.rb +278 -0
  56. data/lib/qrack/transport/buffer09.rb +280 -0
  57. data/lib/qrack/transport/frame08.rb +117 -0
  58. data/lib/qrack/transport/frame09.rb +97 -0
  59. data/spec/spec_08/bunny_spec.rb +77 -0
  60. data/spec/spec_08/connection_spec.rb +25 -0
  61. data/spec/spec_08/exchange_spec.rb +173 -0
  62. data/spec/spec_08/queue_spec.rb +235 -0
  63. data/spec/spec_09/amqp_url_spec.rb +19 -0
  64. data/spec/spec_09/bunny_spec.rb +76 -0
  65. data/spec/spec_09/connection_spec.rb +29 -0
  66. data/spec/spec_09/exchange_spec.rb +173 -0
  67. data/spec/spec_09/queue_spec.rb +248 -0
  68. metadata +151 -0
@@ -0,0 +1,325 @@
1
+ # encoding: utf-8
2
+
3
+ module Bunny
4
+
5
+ # Queues store and forward messages. Queues can be configured in the server or created at runtime.
6
+ # Queues must be attached to at least one exchange in order to receive messages from publishers.
7
+ class Queue09 < Qrack::Queue
8
+ def initialize(client, name, opts = {})
9
+ # check connection to server
10
+ raise Bunny::ConnectionError, 'Not connected to server' if client.status == :not_connected
11
+
12
+ @client = client
13
+ @opts = opts
14
+ @delivery_tag = nil
15
+
16
+ # Queues without a given name are named by the server and are generally
17
+ # bound to the process that created them.
18
+ if !name
19
+ opts = {
20
+ :passive => false,
21
+ :durable => false,
22
+ :exclusive => true,
23
+ :auto_delete => true,
24
+ :deprecated_ticket => 0
25
+ }.merge(opts)
26
+ end
27
+
28
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
29
+ # response that will not be sent by the server
30
+ opts.delete(:nowait)
31
+
32
+ opts = { :queue => name || '', :nowait => false, :deprecated_ticket => 0 }.merge(opts)
33
+
34
+ client.send_frame(Qrack::Protocol09::Queue::Declare.new(opts))
35
+
36
+ method = client.next_method
37
+
38
+ client.check_response(method, Qrack::Protocol09::Queue::DeclareOk, "Error declaring queue #{name}")
39
+
40
+ @name = method.queue
41
+ client.queues[@name] = self
42
+ end
43
+
44
+ # @return [Bunny::Consumer] Default consumer associated with this queue (if any), or nil
45
+ # @note Default consumer is the one registered with the convenience {Bunny::Queue#subscribe} method. It has no special properties of any kind.
46
+ # @see Queue#subscribe
47
+ # @see Bunny::Consumer
48
+ # @api public
49
+ def default_consumer
50
+ @default_consumer
51
+ end
52
+
53
+ # @return [Class]
54
+ # @private
55
+ def self.consumer_class
56
+ # Bunny::Consumer
57
+ Bunny::Subscription09
58
+ end # self.consumer_class
59
+
60
+ # Acknowledges one or more messages delivered via the _Deliver_ or _Get_-_Ok_ methods. The client can
61
+ # ask to confirm a single message or a set of messages up to and including a specific message.
62
+ #
63
+ # @option opts [String] :delivery_tag
64
+ #
65
+ # @option opts [Boolean] :multiple (false)
66
+ # If set to @true@, the delivery tag is treated as "up to and including",
67
+ # so that the client can acknowledge multiple messages with a single method.
68
+ # If set to @false@, the delivery tag refers to a single message.
69
+ # If the multiple field is @true@, and the delivery tag is zero,
70
+ # tells the server to acknowledge all outstanding messages.
71
+ def ack(opts = {})
72
+ # Set delivery tag
73
+ if delivery_tag.nil? and opts[:delivery_tag].nil?
74
+ raise Bunny::AcknowledgementError, "No delivery tag received"
75
+ else
76
+ self.delivery_tag = opts[:delivery_tag] if delivery_tag.nil?
77
+ end
78
+
79
+ opts = {:delivery_tag => delivery_tag, :multiple => false}.merge(opts)
80
+
81
+ client.send_frame(Qrack::Protocol09::Basic::Ack.new(opts))
82
+
83
+ # reset delivery tag
84
+ self.delivery_tag = nil
85
+ end
86
+
87
+ # Binds a queue to an exchange. Until a queue is bound it won't receive
88
+ # any messages. Queues are bound to the direct exchange '' by default.
89
+ # If error occurs, a {Bunny::ProtocolError} is raised.
90
+ #
91
+ # @option opts [String] :key
92
+ # Specifies the routing key for the binding. The routing key is used
93
+ # for routing messages depending on the exchange configuration.
94
+ #
95
+ # @option opts [Boolean] :nowait (false)
96
+ # Ignored by Bunny, always @false@.
97
+ #
98
+ # @return [Symbol] @:bind_ok@ if successful.
99
+ def bind(exchange, opts = {})
100
+ exchange = exchange.respond_to?(:name) ? exchange.name : exchange
101
+
102
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
103
+ # response that will not be sent by the server
104
+ opts.delete(:nowait)
105
+
106
+ opts = {
107
+ :queue => name,
108
+ :exchange => exchange,
109
+ :routing_key => opts.delete(:key),
110
+ :nowait => false,
111
+ :deprecated_ticket => 0
112
+ }.merge(opts)
113
+
114
+ client.send_frame(Qrack::Protocol09::Queue::Bind.new(opts))
115
+
116
+ method = client.next_method
117
+
118
+ client.check_response(method, Qrack::Protocol09::Queue::BindOk, "Error binding queue: #{name} to exchange: #{exchange}")
119
+
120
+ # return message
121
+ :bind_ok
122
+ end
123
+
124
+ # Requests that a queue is deleted from broker/server. When a queue is deleted any pending messages
125
+ # are sent to a dead-letter queue if this is defined in the server configuration. Removes reference
126
+ # from queues if successful. If an error occurs raises @Bunny::ProtocolError@.
127
+ #
128
+ # @option opts [Boolean] :if_unused (false)
129
+ # If set to @true@, the server will only delete the queue if it has no consumers.
130
+ # If the queue has consumers the server does not delete it but raises a channel exception instead.
131
+ #
132
+ # @option opts [Boolean] :if_empty (false)
133
+ # If set to @true@, the server will only delete the queue if it has no messages.
134
+ # If the queue is not empty the server raises a channel exception.
135
+ #
136
+ # @option opts [Boolean] :nowait (false)
137
+ # Ignored by Bunny, always @false@.
138
+ #
139
+ # @return [Symbol] @:delete_ok@ if successful
140
+ def delete(opts = {})
141
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
142
+ # response that will not be sent by the server
143
+ opts.delete(:nowait)
144
+
145
+ opts = { :queue => name, :nowait => false, :deprecated_ticket => 0 }.merge(opts)
146
+
147
+ client.send_frame(Qrack::Protocol09::Queue::Delete.new(opts))
148
+
149
+ method = client.next_method
150
+
151
+ client.check_response(method, Qrack::Protocol09::Queue::DeleteOk, "Error deleting queue #{name}")
152
+
153
+ client.queues.delete(name)
154
+
155
+ # return confirmation
156
+ :delete_ok
157
+ end
158
+
159
+ # Gets a message from a queue in a synchronous way. If error occurs, raises _Bunny_::_ProtocolError_.
160
+ #
161
+ # @option opts [Boolean] :ack (false)
162
+ # If set to @false@, the server does not expect an acknowledgement message
163
+ # from the client. If set to @true@, the server expects an acknowledgement
164
+ # message from the client and will re-queue the message if it does not receive
165
+ # one within a time specified by the server.
166
+ #
167
+ # @return [Hash] Hash with @:header@, @:payload@ and @:delivery_details@ keys. @:delivery_details@ is a hash @:consumer_tag@, @:delivery_tag@, @:redelivered@, @:exchange@ and @:routing_key@. If the queue is empty the returned hash will contain: @{:header => nil, :payload => :queue_empty, :delivery_details => nil}@. N.B. If a block is provided then the hash will be passed into the block and the return value will be nil.
168
+ def pop(opts = {}, &blk)
169
+ opts = {
170
+ :queue => name,
171
+ :consumer_tag => name,
172
+ :no_ack => !opts[:ack],
173
+ :nowait => true,
174
+ :deprecated_ticket => 0
175
+ }.merge(opts)
176
+
177
+ client.send_frame(Qrack::Protocol09::Basic::Get.new(opts))
178
+
179
+ method = client.next_method
180
+
181
+ if method.is_a?(Qrack::Protocol09::Basic::GetEmpty) then
182
+ queue_empty = true
183
+ elsif !method.is_a?(Qrack::Protocol09::Basic::GetOk)
184
+ raise Bunny::ProtocolError, "Error getting message from queue #{name}"
185
+ end
186
+
187
+ if !queue_empty
188
+ # get delivery tag to use for acknowledge
189
+ self.delivery_tag = method.delivery_tag if opts[:ack]
190
+
191
+ header = client.next_payload
192
+
193
+ # If maximum frame size is smaller than message payload body then message
194
+ # will have a message header and several message bodies
195
+ msg = ''
196
+ while msg.length < header.size
197
+ msg << client.next_payload
198
+ end
199
+
200
+ msg_hash = {:header => header, :payload => msg, :delivery_details => method.arguments}
201
+
202
+ else
203
+ msg_hash = {:header => nil, :payload => :queue_empty, :delivery_details => nil}
204
+ end
205
+
206
+ # Pass message hash to block or return message hash
207
+ blk ? blk.call(msg_hash) : msg_hash
208
+ end
209
+
210
+ # Removes all messages from a queue. It does not cancel consumers. Purged messages are deleted
211
+ # without any formal "undo" mechanism. If an error occurs raises {Bunny::ProtocolError}.
212
+ #
213
+ # @option opts [Boolean] :nowait (false)
214
+ # Ignored by Bunny, always @false@.
215
+ #
216
+ # @return [Symbol] @:purge_ok@ if successful
217
+ def purge(opts = {})
218
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
219
+ # response that will not be sent by the server
220
+ opts.delete(:nowait)
221
+
222
+ opts = { :queue => name, :nowait => false, :deprecated_ticket => 0 }.merge(opts)
223
+
224
+ client.send_frame(Qrack::Protocol09::Queue::Purge.new(opts))
225
+
226
+ method = client.next_method
227
+
228
+ client.check_response(method, Qrack::Protocol09::Queue::PurgeOk, "Error purging queue #{name}")
229
+
230
+ # return confirmation
231
+ :purge_ok
232
+ end
233
+
234
+ # @return [Hash] Hash with keys @:message_count@ and @consumer_count@.
235
+ def status
236
+ opts = { :queue => name, :passive => true, :deprecated_ticket => 0 }
237
+ client.send_frame(Qrack::Protocol09::Queue::Declare.new(opts))
238
+
239
+ method = client.next_method
240
+ {:message_count => method.message_count, :consumer_count => method.consumer_count}
241
+ end
242
+
243
+ def subscribe(opts = {}, &blk)
244
+ raise RuntimeError.new("This queue already has default consumer. Please instantiate Bunny::Consumer directly and call its #consume method to register additional consumers.") if @default_consumer && ! opts[:consumer_tag]
245
+
246
+ # Create a subscription.
247
+ @default_consumer = self.class.consumer_class.new(client, self, opts)
248
+ @default_consumer.consume(&blk)
249
+ end
250
+
251
+ # Removes a queue binding from an exchange. If error occurs, a _Bunny_::_ProtocolError_ is raised.
252
+ #
253
+ # @option opts [String] :key
254
+ # Specifies the routing key for the binding.
255
+ #
256
+ # @option opts [Boolean] :nowait (false)
257
+ # Ignored by Bunny, always @false@.
258
+ #
259
+ # @return [Symbol] @:unbind_ok@ if successful.
260
+ def unbind(exchange, opts = {})
261
+ exchange = exchange.respond_to?(:name) ? exchange.name : exchange
262
+
263
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
264
+ # response that will not be sent by the server
265
+ opts.delete(:nowait)
266
+
267
+ opts = {
268
+ :queue => name,
269
+ :exchange => exchange,
270
+ :routing_key => opts.delete(:key),
271
+ :nowait => false,
272
+ :deprecated_ticket => 0
273
+ }.merge(opts)
274
+
275
+ client.send_frame(Qrack::Protocol09::Queue::Unbind.new(opts))
276
+
277
+ method = client.next_method
278
+
279
+ client.check_response(method, Qrack::Protocol09::Queue::UnbindOk, "Error unbinding queue #{name}")
280
+
281
+ # return message
282
+ :unbind_ok
283
+ end
284
+
285
+ # Cancels a consumer. This does not affect already delivered messages, but it does mean
286
+ # the server will not send any more messages for that consumer.
287
+ #
288
+ # @option opts [String] :consumer_tag
289
+ # Specifies the identifier for the consumer.
290
+ #
291
+ # @option opts [Boolean] :nowait (false)
292
+ # Ignored by Bunny, always @false@.
293
+ #
294
+ # @return [Symbol] @:unsubscribe_ok@ if successful
295
+ def unsubscribe(opts = {})
296
+ # Default consumer_tag from subscription if not passed in
297
+ consumer_tag = @default_consumer ? @default_consumer.consumer_tag : opts[:consumer_tag]
298
+
299
+ # Must have consumer tag to tell server what to unsubscribe
300
+ raise Bunny::UnsubscribeError,
301
+ "No consumer tag received" if !consumer_tag
302
+
303
+ # Cancel consumer
304
+ client.send_frame(Qrack::Protocol09::Basic::Cancel.new(:consumer_tag => consumer_tag, :nowait => false))
305
+
306
+ method = client.next_method
307
+
308
+ client.check_response(method, Qrack::Protocol09::Basic::CancelOk, "Error unsubscribing from queue #{name}")
309
+
310
+ # Reset subscription
311
+ @default_consumer = nil
312
+
313
+ # Return confirmation
314
+ :unsubscribe_ok
315
+ end
316
+
317
+ private
318
+
319
+ def exchange
320
+ @exchange ||= Bunny::Exchange09.new(client, '', :type => :direct, :key => name, :reserved_1 => 0, :reserved_2 => false, :reserved_3 => false)
321
+ end
322
+
323
+ end
324
+
325
+ end
@@ -0,0 +1,87 @@
1
+ # encoding: utf-8
2
+
3
+ module Bunny
4
+
5
+ =begin rdoc
6
+
7
+ === DESCRIPTION:
8
+
9
+ Asks the server to start a "consumer", which is a transient request for messages from a specific
10
+ queue. Consumers last as long as the channel they were created on, or until the client cancels them
11
+ with an _unsubscribe_. Every time a message reaches the queue it is passed to the _blk_ for
12
+ processing. If error occurs, _Bunny_::_ProtocolError_ is raised.
13
+
14
+ ==== OPTIONS:
15
+ * <tt>:consumer_tag => '_tag_'</tt> - Specifies the identifier for the consumer. The consumer tag is
16
+ local to a connection, so two clients can use the same consumer tags. If this option is not
17
+ specified a server generated name is used.
18
+ * <tt>:ack => false (_default_) or true</tt> - If set to _false_, the server does not expect an
19
+ acknowledgement message from the client. If set to _true_, the server expects an acknowledgement
20
+ message from the client and will re-queue the message if it does not receive one within a time specified
21
+ by the server.
22
+ * <tt>:exclusive => true or false (_default_)</tt> - Request exclusive consumer access, meaning
23
+ only this consumer can access the queue.
24
+ * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
25
+ * <tt>:timeout => number of seconds - The subscribe loop will continue to wait for
26
+ messages until terminated (Ctrl-C or kill command) or this timeout interval is reached.
27
+ * <tt>:message_max => max number messages to process</tt> - When the required number of messages
28
+ is processed subscribe loop is exited.
29
+
30
+ ==== OPERATION:
31
+
32
+ Passes a hash of message information to the block, if one has been supplied. The hash contains
33
+ :header, :payload and :delivery_details. The structure of the data is as follows -
34
+
35
+ :header has instance variables -
36
+ @klass
37
+ @size
38
+ @weight
39
+ @properties is a hash containing -
40
+ :content_type
41
+ :delivery_mode
42
+ :priority
43
+
44
+ :payload contains the message contents
45
+
46
+ :delivery details is a hash containing -
47
+ :consumer_tag
48
+ :delivery_tag
49
+ :redelivered
50
+ :exchange
51
+ :routing_key
52
+
53
+ If the :timeout option is specified then the subscription will
54
+ automatically cease if the given number of seconds passes with no
55
+ message arriving.
56
+
57
+ ==== EXAMPLES
58
+
59
+ my_queue.subscribe(:timeout => 5) {|msg| puts msg[:payload]}
60
+
61
+ my_queue.subscribe(:message_max => 10, :ack => true) {|msg| puts msg[:payload]}
62
+
63
+ =end
64
+
65
+ class Subscription < Bunny::Consumer
66
+
67
+ def setup_consumer
68
+ subscription_options = {
69
+ :queue => queue.name,
70
+ :consumer_tag => consumer_tag,
71
+ :no_ack => !ack,
72
+ :exclusive => exclusive,
73
+ :nowait => false
74
+ }.merge(@opts)
75
+
76
+ client.send_frame(Qrack::Protocol::Basic::Consume.new(subscription_options))
77
+
78
+ method = client.next_method
79
+
80
+ client.check_response(method, Qrack::Protocol::Basic::ConsumeOk, "Error subscribing to queue #{queue.name}")
81
+
82
+ @consumer_tag = method.consumer_tag
83
+ end
84
+
85
+ end
86
+
87
+ end
@@ -0,0 +1,87 @@
1
+ # encoding: utf-8
2
+
3
+ module Bunny
4
+
5
+ # Asks the server to start a "consumer", which is a transient request for messages from a specific
6
+ # queue. Consumers last as long as the channel they were created on, or until the client cancels them
7
+ # with an @unsubscribe@. Every time a message reaches the queue it is passed to the @blk@ for
8
+ # processing. If error occurs, {Bunny::ProtocolError} is raised.
9
+ #
10
+ # @option opts [String] :consumer_tag
11
+ # Specifies the identifier for the consumer. The consumer tag is
12
+ # local to a connection, so two clients can use the same consumer tags.
13
+ # If this option is not specified a server generated name is used.
14
+ #
15
+ # @option opts [Boolean] :ack (false)
16
+ # If set to @false@, the server does not expect an acknowledgement message
17
+ # from the client. If set to @true, the server expects an acknowledgement
18
+ # message from the client and will re-queue the message if it does not
19
+ # receive one within a time specified by the server.
20
+ #
21
+ # @option opts [Boolean] :exclusive (false)
22
+ # Request exclusive consumer access, meaning only this consumer can access the queue.
23
+ #
24
+ # @option opts [Boolean] :nowait (false)
25
+ # Ignored by Bunny, always @false@.
26
+ #
27
+ # @option opts [Numeric] :timeout
28
+ # The subscribe loop will continue to wait for messages
29
+ # until terminated (Ctrl-C or kill command) or this timeout interval is reached.
30
+ #
31
+ # @option opts [Integer] :message_max
32
+ # When the required number of messages is processed subscribe loop is exited.
33
+ #
34
+ # h2. Operation
35
+ #
36
+ # Passes a hash of message information to the block, if one has been supplied. The hash contains
37
+ # :header, :payload and :delivery_details. The structure of the data is as follows -
38
+ #
39
+ # :header has instance variables -
40
+ # @klass
41
+ # @size
42
+ # @weight
43
+ # @properties is a hash containing -
44
+ # :content_type
45
+ # :delivery_mode
46
+ # :priority
47
+ #
48
+ # :payload contains the message contents
49
+ #
50
+ # :delivery details is a hash containing -
51
+ # :consumer_tag
52
+ # :delivery_tag
53
+ # :redelivered
54
+ # :exchange
55
+ # :routing_key
56
+ #
57
+ # If the :timeout option is specified then the subscription will
58
+ # automatically cease if the given number of seconds passes with no
59
+ # message arriving.
60
+ #
61
+ # @example
62
+ # my_queue.subscribe(timeout: 5) { |msg| puts msg[:payload] }
63
+ # my_queue.subscribe(message_max: 10, ack: true) { |msg| puts msg[:payload] }
64
+ class Subscription09 < Bunny::Consumer
65
+
66
+ def setup_consumer
67
+ subscription_options = {
68
+ :deprecated_ticket => 0,
69
+ :queue => queue.name,
70
+ :consumer_tag => consumer_tag,
71
+ :no_ack => !ack,
72
+ :exclusive => exclusive,
73
+ :nowait => false
74
+ }.merge(@opts)
75
+
76
+ client.send_frame(Qrack::Protocol09::Basic::Consume.new(subscription_options))
77
+
78
+ method = client.next_method
79
+
80
+ client.check_response(method, Qrack::Protocol09::Basic::ConsumeOk, "Error subscribing to queue #{queue.name}")
81
+
82
+ @consumer_tag = method.consumer_tag
83
+ end
84
+
85
+ end
86
+
87
+ end
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+
3
+ module Bunny
4
+ # Used for ruby < 1.9.x
5
+ class SystemTimer < ::SystemTimer
6
+
7
+ def timeout(seconds, exception)
8
+ timeout_after(seconds) do
9
+ yield
10
+ end
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+
3
+ module Bunny
4
+ VERSION = "0.0.1"
5
+ end
data/lib/bunny.rb ADDED
@@ -0,0 +1,109 @@
1
+ # encoding: utf-8
2
+
3
+ require "socket"
4
+ require "thread"
5
+ require "timeout"
6
+ require "logger"
7
+
8
+ require File.expand_path("../bunny/version", __FILE__)
9
+ # if we don't require the version file the same way as in the gemspec,
10
+ # the version file will be loaded twice. and we hate warnings.
11
+
12
+ module Bunny
13
+
14
+ class ConnectionError < StandardError; end
15
+ class ForcedChannelCloseError < StandardError; end
16
+ class ForcedConnectionCloseError < StandardError; end
17
+ class MessageError < StandardError; end
18
+ class ProtocolError < StandardError; end
19
+ class ServerDownError < StandardError; end
20
+ class UnsubscribeError < StandardError; end
21
+ class AcknowledgementError < StandardError; end
22
+
23
+ # Returns the Bunny version number
24
+
25
+ def self.version
26
+ VERSION
27
+ end
28
+
29
+ # Print deprecation warning.
30
+ def self.deprecation_warning(method, version, explanation)
31
+ warn "~ #{method} will be removed in Bunny #{version}. #{explanation}"
32
+ end
33
+
34
+ # Instantiates new Bunny::Client
35
+
36
+ def self.new(connection_string_or_opts = Hash.new, opts = Hash.new)
37
+ # Set up Bunny according to AMQP spec version required
38
+ if connection_string_or_opts.respond_to?(:keys) && opts.empty?
39
+ opts = connection_string_or_opts
40
+ end
41
+
42
+ spec_version = opts[:spec] || '08'
43
+
44
+ # Return client
45
+ setup(spec_version, connection_string_or_opts, opts)
46
+ end
47
+
48
+ # Runs a code block using a short-lived connection
49
+
50
+ def self.run(opts = {}, &block)
51
+ raise ArgumentError, 'Bunny#run requires a block' unless block
52
+
53
+ # Set up Bunny according to AMQP spec version required
54
+ spec_version = opts[:spec] || '08'
55
+ client = setup(spec_version, opts)
56
+
57
+ begin
58
+ client.start
59
+ block.call(client)
60
+ ensure
61
+ client.stop
62
+ end
63
+
64
+ # Return success
65
+ :run_ok
66
+ end
67
+
68
+ Timer = if RUBY_VERSION < "1.9"
69
+ begin
70
+ require File.expand_path(File.join(File.dirname(__FILE__), 'system_timer.rb'))
71
+ Bunny::SystemTimer
72
+ rescue LoadError
73
+ Timeout
74
+ end
75
+ else
76
+ Timeout
77
+ end
78
+
79
+ private
80
+
81
+ def self.setup(version, *args)
82
+ if version == '08'
83
+ # AMQP 0-8 specification
84
+ require 'qrack/qrack08'
85
+ require 'bunny/client08'
86
+ require 'bunny/exchange08'
87
+ require 'bunny/queue08'
88
+ require 'bunny/channel08'
89
+ require 'bunny/subscription08'
90
+
91
+ client = Bunny::Client.new(*args)
92
+ else
93
+ # AMQP 0-9-1 specification
94
+ require 'qrack/qrack09'
95
+ require 'bunny/client09'
96
+ require 'bunny/exchange09'
97
+ require 'bunny/queue09'
98
+ require 'bunny/channel09'
99
+ require 'bunny/subscription09'
100
+
101
+ client = Bunny::Client09.new(*args)
102
+ end
103
+
104
+ include Qrack
105
+
106
+ client
107
+ end
108
+
109
+ end