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,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