sparqcode_bunny 0.0.1

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.
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,374 @@
1
+ # encoding: utf-8
2
+
3
+ module Bunny
4
+
5
+ # The Client class provides the major Bunny API methods.
6
+ class Client09 < Qrack::Client
7
+
8
+ # Sets up a Bunny::Client object ready for connection to a broker.
9
+ # {Client.status} is set to @:not_connected@.
10
+ #
11
+ # @option opts [String] :host ("localhost")
12
+ # @option opts [Integer] :port (5672 or 5671 if :ssl set to true)
13
+ # @option opts [String] :vhost ("/")
14
+ # @option opts [String] :user ("guest")
15
+ # @option opts [String] :pass ("guest")
16
+ # @option opts [Boolean] :ssl (false)
17
+ # If set to @true@, ssl encryption will be used and port will default to 5671.
18
+ # @option opts [Boolean] :verify_ssl (true)
19
+ # If ssl is enabled, this will cause OpenSSL to validate
20
+ # the server certificate unless this parameter is set to @false@.
21
+ # @option opts [String] :logfile (nil)
22
+ # @option opts [Boolean] :logging (false)
23
+ # If set to @true@, session information is sent to STDOUT if @:logfile@
24
+ # has not been specified. Otherwise, session information is written to @:logfile@.
25
+ # @option opts [Integer] :frame_max (131072)
26
+ # Maximum frame size in bytes.
27
+ # @option opts [Integer] :channel_max (0)
28
+ # Maximum number of channels. Defaults to 0 which means no maximum.
29
+ # @option opts [Integer] :heartbeat (0)
30
+ # Number of seconds. Defaults to 0 which means no heartbeat.
31
+ # @option opts [Integer] :connect_timeout (5)
32
+ # Number of seconds before {Qrack::ConnectionTimeout} is raised.@
33
+ def initialize(connection_string_or_opts = Hash.new, opts = Hash.new)
34
+ super
35
+ @spec = '0-9-1'
36
+ @port = self.__opts__[:port] || (self.__opts__[:ssl] ? Qrack::Protocol09::SSL_PORT : Qrack::Protocol09::PORT)
37
+ end
38
+
39
+ # Checks response from AMQP methods and takes appropriate action
40
+ def check_response(received_method, expected_method, err_msg, err_class = Bunny::ProtocolError)
41
+ case
42
+ when received_method.is_a?(Qrack::Protocol09::Connection::Close)
43
+ # Clean up the socket
44
+ close_socket
45
+
46
+ raise Bunny::ForcedConnectionCloseError, "Error Reply Code: #{received_method.reply_code}\nError Reply Text: #{received_method.reply_text}"
47
+
48
+ when received_method.is_a?(Qrack::Protocol09::Channel::Close)
49
+ # Clean up the channel
50
+ channel.active = false
51
+
52
+ raise Bunny::ForcedChannelCloseError, "Error Reply Code: #{received_method.reply_code}\nError Reply Text: #{received_method.reply_text}"
53
+
54
+ when !received_method.is_a?(expected_method)
55
+ raise err_class, err_msg
56
+
57
+ else
58
+ :response_ok
59
+ end
60
+ end
61
+
62
+ def close_connection
63
+ # Set client channel to zero
64
+ switch_channel(0)
65
+
66
+ send_frame(Qrack::Protocol09::Connection::Close.new(:reply_code => 200, :reply_text => 'Goodbye', :class_id => 0, :method_id => 0))
67
+
68
+ method = next_method
69
+
70
+ check_response(method, Qrack::Protocol09::Connection::CloseOk, "Error closing connection")
71
+
72
+ end
73
+
74
+ def create_channel
75
+ channels.each do |c|
76
+ return c if (!c.open? and c.number != 0)
77
+ end
78
+ # If no channel to re-use instantiate new one
79
+ Bunny::Channel09.new(self)
80
+ end
81
+
82
+ # Declares an exchange to the broker/server. If the exchange does not exist, a new one is created
83
+ # using the arguments passed in. If the exchange already exists, a reference to it is created, provided
84
+ # that the arguments passed in do not conflict with the existing attributes of the exchange. If an error
85
+ # occurs a _Bunny_::_ProtocolError_ is raised.
86
+ #
87
+ # @option opts [Symbol] :type (:direct)
88
+ # One of :direct@, @:fanout@, @:topic@, or @:headers@.
89
+ #
90
+ # @option opts [Boolean] :passive
91
+ # If set to @true@, the server will not create the exchange.
92
+ # The client can use this to check whether an exchange exists without modifying the server state.
93
+ #
94
+ # @option opts [Boolean] :durable (false)
95
+ # If set to @true@ when creating a new exchange, the exchange
96
+ # will be marked as durable. Durable exchanges remain active
97
+ # when a server restarts. Non-durable exchanges (transient exchanges)
98
+ # are purged if/when a server restarts.
99
+ #
100
+ # @option opts [Boolean] :auto_delete (false)
101
+ # If set to @true@, the exchange is deleted when all queues have finished using it.
102
+ #
103
+ # @option opts [Boolean] :nowait (false)
104
+ # Ignored by Bunny, always @false@.
105
+ #
106
+ # @return [Bunny::Exchange09]
107
+ def exchange(name, opts = {})
108
+ exchanges[name] || Bunny::Exchange09.new(self, name, opts)
109
+ end
110
+
111
+ def init_connection
112
+ write(Qrack::Protocol09::HEADER)
113
+ write([0, Qrack::Protocol09::VERSION_MAJOR, Qrack::Protocol09::VERSION_MINOR, Qrack::Protocol09::REVISION].pack('C4'))
114
+
115
+ frame = next_frame
116
+ if frame.nil? or !frame.payload.is_a?(Qrack::Protocol09::Connection::Start)
117
+ raise Bunny::ProtocolError, 'Connection initiation failed'
118
+ end
119
+ end
120
+
121
+ def next_frame(opts = {})
122
+ frame = nil
123
+
124
+ case
125
+ when channel.frame_buffer.size > 0
126
+ frame = channel.frame_buffer.shift
127
+ when (timeout = opts[:timeout]) && timeout > 0
128
+ Bunny::Timer::timeout(timeout, Qrack::FrameTimeout) do
129
+ frame = Qrack::Transport09::Frame.parse(buffer)
130
+ end
131
+ else
132
+ frame = Qrack::Transport09::Frame.parse(buffer)
133
+ end
134
+
135
+ @logger.info("received") { frame } if @logging
136
+
137
+ raise Bunny::ConnectionError, 'No connection to server' if (frame.nil? and !connecting?)
138
+
139
+ # Monitor server activity and discard heartbeats
140
+ @message_in = true
141
+
142
+ case
143
+ when frame.is_a?(Qrack::Transport09::Heartbeat)
144
+ next_frame(opts)
145
+ when frame.nil?
146
+ frame
147
+ when ((frame.channel != channel.number) and (frame.channel != 0))
148
+ channel.frame_buffer << frame
149
+ next_frame(opts)
150
+ else
151
+ frame
152
+ end
153
+
154
+ end
155
+
156
+ def open_connection
157
+ client_props = { :platform => 'Ruby', :product => 'Bunny', :information => 'http://github.com/ruby-amqp/bunny', :version => VERSION }
158
+ start_opts = {
159
+ :client_properties => client_props,
160
+ :mechanism => 'PLAIN',
161
+ :response => "\0" + @user + "\0" + @pass,
162
+ :locale => 'en_US'
163
+ }
164
+ send_frame(Qrack::Protocol09::Connection::StartOk.new(start_opts))
165
+
166
+ frame = next_frame
167
+ raise Bunny::ProtocolError, "Connection failed - user: #{@user}" if frame.nil?
168
+
169
+ method = frame.payload
170
+
171
+ if method.is_a?(Qrack::Protocol09::Connection::Tune)
172
+ send_frame(Qrack::Protocol09::Connection::TuneOk.new(:channel_max => @channel_max, :frame_max => @frame_max, :heartbeat => @heartbeat))
173
+ end
174
+
175
+ send_frame(Qrack::Protocol09::Connection::Open.new(:virtual_host => @vhost, :reserved_1 => 0, :reserved_2 => false))
176
+
177
+ raise Bunny::ProtocolError, 'Cannot open connection' unless next_method.is_a?(Qrack::Protocol09::Connection::OpenOk)
178
+ end
179
+
180
+ # Requests a specific quality of service. The QoS can be specified for the current channel
181
+ # or for all channels on the connection. The particular properties and semantics of a QoS
182
+ # method always depend on the content class semantics. Though the QoS method could in principle
183
+ # apply to both peers, it is currently meaningful only for the server.
184
+ #
185
+ # @option opts [Integer] :prefetch_size (0)
186
+ # Size in number of octets. The client can request that messages be sent in advance
187
+ # so that when the client finishes processing a message, the following message is
188
+ # already held locally, rather than needing to be sent down the channel. refetching
189
+ # gives a performance improvement. This field specifies the prefetch window size
190
+ # in octets. The server will send a message in advance if it is equal to or smaller
191
+ # in size than the available prefetch size (and also falls into other prefetch limits).
192
+ # May be set to zero, meaning "no specific limit", although other prefetch limits may
193
+ # still apply. The prefetch-size is ignored if the no-ack option is set.
194
+ #
195
+ # @option opts [Integer] :prefetch_count (1)
196
+ # Number of messages to prefetch. Specifies a prefetch window in terms of whole messages.
197
+ # This field may be used in combination with the prefetch-size field; a message will only
198
+ # be sent in advance if both prefetch windows (and those at the channel and connection level)
199
+ # allow it. The prefetch-count is ignored if the no-ack option is set.
200
+ #
201
+ # @option opts [Boolean] :global (false)
202
+ # By default the QoS settings apply to the current channel only. If set to true,
203
+ # they are applied to the entire connection.
204
+ #
205
+ # @return [Symbol] @:qos_ok@ if successful.
206
+ def qos(opts = {})
207
+ send_frame(Qrack::Protocol09::Basic::Qos.new({ :prefetch_size => 0, :prefetch_count => 1, :global => false }.merge(opts)))
208
+
209
+ method = next_method
210
+
211
+ check_response(method, Qrack::Protocol09::Basic::QosOk, "Error specifying Quality of Service")
212
+
213
+ # return confirmation
214
+ :qos_ok
215
+ end
216
+
217
+ # Declares a queue to the broker/server. If the queue does not exist, a new one is created
218
+ # using the arguments passed in. If the queue already exists, a reference to it is created, provided
219
+ # that the arguments passed in do not conflict with the existing attributes of the queue. If an error
220
+ # occurs a {Bunny::ProtocolError} is raised.
221
+ #
222
+ # @option opts [Boolean] :passive (false)
223
+ # If set to @true@, the server will not create the queue. The client can use this to check
224
+ # whether a queue exists without modifying the server state.
225
+ #
226
+ # @option opts [Boolean] :durable (false)
227
+ # If set to @true@ when creating a new queue, the queue will be marked as durable.
228
+ # Durable queues remain active when a server restarts. Non-durable queues (transient ones)
229
+ # are purged if/when a server restarts. Note that durable queues do not necessarily hold
230
+ # persistent messages, although it does not make sense to send persistent messages
231
+ # to a transient queue.
232
+ #
233
+ # @option opts [Boolean] :exclusive (false)
234
+ # If set to @true@, requests an exclusive queue. Exclusive queues may only be consumed
235
+ # from by the current connection. Setting the 'exclusive' flag always implies 'auto-delete'.
236
+ #
237
+ # @option opts [Boolean] :auto_delete (false)
238
+ # If set to @true@, the queue is deleted when all consumers have finished using it.
239
+ # Last consumer can be cancelled either explicitly or because its channel is closed.
240
+ # If there has never been a consumer on the queue, it is not deleted.
241
+ #
242
+ # @option opts [Boolean] :nowait (false)
243
+ # Ignored by Bunny, always @false@.
244
+ #
245
+ # @return [Bunny::Queue09]
246
+ def queue(name = nil, opts = {})
247
+ if name.is_a?(Hash)
248
+ opts = name
249
+ name = nil
250
+ end
251
+
252
+ # Queue is responsible for placing itself in the list of queues
253
+ queues[name] || Bunny::Queue09.new(self, name, opts)
254
+ end
255
+
256
+ # Asks the broker to redeliver all unacknowledged messages on a specified channel. Zero or
257
+ # more messages may be redelivered.
258
+ #
259
+ # @option opts [Boolean] :requeue (false)
260
+ # If set to @false@, the message will be redelivered to the original recipient.
261
+ # If set to @true@, the server will attempt to requeue the message, potentially
262
+ # then delivering it to an alternative subscriber.
263
+ def recover(opts = {})
264
+ send_frame(Qrack::Protocol09::Basic::Recover.new({ :requeue => false }.merge(opts)))
265
+ end
266
+
267
+ def send_frame(*args)
268
+ args.each do |data|
269
+ data = data.to_frame(channel.number) unless data.is_a?(Qrack::Transport09::Frame)
270
+ data.channel = channel.number
271
+
272
+ @logger.info("send") { data } if @logging
273
+ write(data.to_s)
274
+
275
+ # Monitor client activity for heartbeat purposes
276
+ @message_out = true
277
+ end
278
+
279
+ nil
280
+ end
281
+
282
+ def send_heartbeat
283
+ # Create a new heartbeat frame
284
+ hb = Qrack::Transport09::Heartbeat.new('')
285
+ # Channel 0 must be used
286
+ switch_channel(0) if @channel.number > 0
287
+ # Send the heartbeat to server
288
+ send_frame(hb)
289
+ end
290
+
291
+ # Opens a communication channel and starts a connection. If an error occurs, a
292
+ # {Bunny::ProtocolError} is raised. If successful, {Client.status} is set to @:connected@.
293
+ #
294
+ # @return [Symbol] @:connected@ if successful.
295
+ def start_session
296
+ @connecting = true
297
+
298
+ # Create/get socket
299
+ socket
300
+
301
+ # Initiate connection
302
+ init_connection
303
+
304
+ # Open connection
305
+ open_connection
306
+
307
+ # Open another channel because channel zero is used for specific purposes
308
+ c = create_channel()
309
+ c.open
310
+
311
+ @connecting = false
312
+
313
+ # return status
314
+ @status = :connected
315
+ end
316
+
317
+ alias start start_session
318
+
319
+ # This method commits all messages published and acknowledged in
320
+ # the current transaction. A new transaction starts immediately
321
+ # after a commit.
322
+ #
323
+ # @return [Symbol] @:commit_ok@ if successful.
324
+ def tx_commit
325
+ send_frame(Qrack::Protocol09::Tx::Commit.new())
326
+
327
+ method = next_method
328
+
329
+ check_response(method, Qrack::Protocol09::Tx::CommitOk, "Error commiting transaction")
330
+
331
+ # return confirmation
332
+ :commit_ok
333
+ end
334
+
335
+ # This method abandons all messages published and acknowledged in
336
+ # the current transaction. A new transaction starts immediately
337
+ # after a rollback.
338
+ #
339
+ # @return [Symbol] @:rollback_ok@ if successful.
340
+ def tx_rollback
341
+ send_frame(Qrack::Protocol09::Tx::Rollback.new())
342
+
343
+ method = next_method
344
+
345
+ check_response(method, Qrack::Protocol09::Tx::RollbackOk, "Error rolling back transaction")
346
+
347
+ # return confirmation
348
+ :rollback_ok
349
+ end
350
+
351
+ # This method sets the channel to use standard transactions. The
352
+ # client must use this method at least once on a channel before
353
+ # using the Commit or Rollback methods.
354
+ #
355
+ # @return [Symbol] @:select_ok@ if successful.
356
+ def tx_select
357
+ send_frame(Qrack::Protocol09::Tx::Select.new())
358
+
359
+ method = next_method
360
+
361
+ check_response(method, Qrack::Protocol09::Tx::SelectOk, "Error initiating transactions for current channel")
362
+
363
+ # return confirmation
364
+ :select_ok
365
+ end
366
+
367
+ private
368
+
369
+ def buffer
370
+ @buffer ||= Qrack::Transport09::Buffer.new(self)
371
+ end
372
+
373
+ end
374
+ end
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+
3
+ ####################################
4
+ # NOTE: THIS CLASS IS HERE TO MAKE #
5
+ # TRANSITION TO AMQ CLIENT EASIER #
6
+ ####################################
7
+
8
+ require "qrack/subscription"
9
+
10
+ # NOTE: This file is rather a temporary hack to fix
11
+ # https://github.com/ruby-amqp/bunny/issues/9 then
12
+ # some permanent solution. It's mostly copied from
13
+ # the AMQP and AMQ Client gems. Later on we should
14
+ # use AMQ Client directly and just inherit from
15
+ # the AMQ::Client::Sync::Consumer class.
16
+
17
+ module Bunny
18
+
19
+ # AMQP consumers are entities that handle messages delivered
20
+ # to them ("push API" as opposed to "pull API") by AMQP broker.
21
+ # Every consumer is associated with a queue. Consumers can be
22
+ # exclusive (no other consumers can be registered for the same
23
+ # queue) or not (consumers share the queue). In the case of
24
+ # multiple consumers per queue, messages are distributed in
25
+ # round robin manner with respect to channel-level prefetch
26
+ # setting).
27
+ class Consumer < Qrack::Subscription
28
+ def initialize(*args)
29
+ super(*args)
30
+ @consumer_tag ||= (1..32).to_a.shuffle.join
31
+ end
32
+
33
+ alias_method :consume, :start
34
+ end
35
+ end
@@ -0,0 +1,171 @@
1
+ # encoding: utf-8
2
+
3
+ module Bunny
4
+
5
+ =begin rdoc
6
+
7
+ === DESCRIPTION:
8
+
9
+ *Exchanges* are the routing and distribution hub of AMQP. All messages that Bunny sends
10
+ to an AMQP broker/server _have_ to pass through an exchange in order to be routed to a
11
+ destination queue. The AMQP specification defines the types of exchange that you can create.
12
+
13
+ At the time of writing there are four (4) types of exchange defined -
14
+
15
+ * <tt>:direct</tt>
16
+ * <tt>:fanout</tt>
17
+ * <tt>:topic</tt>
18
+ * <tt>:headers</tt>
19
+
20
+ AMQP-compliant brokers/servers are required to provide default exchanges for the _direct_ and
21
+ _fanout_ exchange types. All default exchanges are prefixed with <tt>'amq.'</tt>, for example -
22
+
23
+ * <tt>amq.direct</tt>
24
+ * <tt>amq.fanout</tt>
25
+ * <tt>amq.topic</tt>
26
+ * <tt>amq.match</tt> or <tt>amq.headers</tt>
27
+
28
+ If you want more information about exchanges, please consult the documentation for your
29
+ target broker/server or visit the {AMQP website}[http://www.amqp.org] to find the version of the
30
+ specification that applies to your target broker/server.
31
+
32
+ =end
33
+
34
+ class Exchange
35
+
36
+ attr_reader :client, :type, :name, :opts, :key
37
+
38
+ def initialize(client, name, opts = {})
39
+ # check connection to server
40
+ raise Bunny::ConnectionError, 'Not connected to server' if client.status == :not_connected
41
+
42
+ @client, @name, @opts = client, name, opts
43
+
44
+ # set up the exchange type catering for default names
45
+ if name =~ /^amq\.(.+)$/
46
+ predeclared = true
47
+ new_type = $1
48
+ # handle 'amq.match' default
49
+ new_type = 'headers' if new_type == 'match'
50
+ @type = new_type.to_sym
51
+ else
52
+ @type = opts[:type] || :direct
53
+ end
54
+
55
+ @key = opts[:key]
56
+ @client.exchanges[@name] ||= self
57
+
58
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
59
+ # response that will not be sent by the server
60
+ opts.delete(:nowait)
61
+
62
+ unless predeclared or name == ''
63
+ opts = { :exchange => name, :type => type, :nowait => false }.merge(opts)
64
+
65
+ client.send_frame(Qrack::Protocol::Exchange::Declare.new(opts))
66
+
67
+ method = client.next_method
68
+
69
+ client.check_response(method, Qrack::Protocol::Exchange::DeclareOk, "Error declaring exchange #{name}: type = #{type}")
70
+ end
71
+ end
72
+
73
+ =begin rdoc
74
+
75
+ === DESCRIPTION:
76
+
77
+ Requests that an exchange is deleted from broker/server. Removes reference from exchanges
78
+ if successful. If an error occurs raises _Bunny_::_ProtocolError_.
79
+
80
+ ==== Options:
81
+
82
+ * <tt>:if_unused => true or false (_default_)</tt> - If set to _true_, the server will only
83
+ delete the exchange if it has no queue bindings. If the exchange has queue bindings the
84
+ server does not delete it but raises a channel exception instead.
85
+ * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
86
+
87
+ ==== Returns:
88
+
89
+ <tt>:delete_ok</tt> if successful
90
+ =end
91
+
92
+ def delete(opts = {})
93
+ # ignore the :nowait option if passed, otherwise program will hang waiting for a
94
+ # response that will not be sent by the server
95
+ opts.delete(:nowait)
96
+
97
+ client.send_frame(Qrack::Protocol::Exchange::Delete.new({ :exchange => name, :nowait => false }.merge(opts)))
98
+
99
+ method = client.next_method
100
+
101
+ client.check_response(method, Qrack::Protocol::Exchange::DeleteOk, "Error deleting exchange #{name}")
102
+
103
+ client.exchanges.delete(name)
104
+
105
+ # return confirmation
106
+ :delete_ok
107
+ end
108
+
109
+ =begin rdoc
110
+
111
+ === DESCRIPTION:
112
+
113
+ Publishes a message to a specific exchange. The message will be routed to queues as defined
114
+ by the exchange configuration and distributed to any active consumers when the transaction,
115
+ if any, is committed.
116
+
117
+ ==== OPTIONS:
118
+
119
+ * <tt>:key => 'routing_key'</tt> - Specifies the routing key for the message. The routing key is
120
+ used for routing messages depending on the exchange configuration.
121
+ * <tt>:content_type => 'content/type'</tt> - Specifies the content type to use for the message.
122
+ * <tt>:mandatory => true or false (_default_)</tt> - Tells the server how to react if the message
123
+ cannot be routed to a queue. If set to _true_, the server will return an unroutable message
124
+ with a Return method. If this flag is zero, the server silently drops the message.
125
+ * <tt>:immediate => true or false (_default_)</tt> - Tells the server how to react if the message
126
+ cannot be routed to a queue consumer immediately. If set to _true_, the server will return an
127
+ undeliverable message with a Return method. If set to _false_, the server will queue the message,
128
+ but with no guarantee that it will ever be consumed.
129
+ * <tt>:persistent => true or false (_default_)</tt> - Tells the server whether to persist the message
130
+ If set to _true_, the message will be persisted to disk and not lost if the server restarts.
131
+ If set to _false_, the message will not be persisted across server restart. Setting to _true_
132
+ incurs a performance penalty as there is an extra cost associated with disk access.
133
+
134
+ ==== RETURNS:
135
+
136
+ nil
137
+
138
+ =end
139
+
140
+ def publish(data, opts = {})
141
+ opts = opts.dup
142
+ out = []
143
+
144
+ # Set up options
145
+ routing_key = opts.delete(:key) || key
146
+ mandatory = opts.delete(:mandatory)
147
+ immediate = opts.delete(:immediate)
148
+ delivery_mode = opts.delete(:persistent) ? 2 : 1
149
+ content_type = opts.delete(:content_type) || 'application/octet-stream'
150
+
151
+ out << Qrack::Protocol::Basic::Publish.new({ :exchange => name,
152
+ :routing_key => routing_key,
153
+ :mandatory => mandatory,
154
+ :immediate => immediate })
155
+ data = data.to_s
156
+ out << Qrack::Protocol::Header.new(
157
+ Qrack::Protocol::Basic,
158
+ data.bytesize, {
159
+ :content_type => content_type,
160
+ :delivery_mode => delivery_mode,
161
+ :priority => 0
162
+ }.merge(opts)
163
+ )
164
+ out << Qrack::Transport::Body.new(data)
165
+
166
+ client.send_frame(*out)
167
+ end
168
+
169
+ end
170
+
171
+ end