bunny 0.6.3.rc2 → 0.7

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 +8 -0
  2. data/.rspec +3 -0
  3. data/.travis.yml +15 -0
  4. data/.yardopts +9 -0
  5. data/CHANGELOG +3 -0
  6. data/Gemfile +39 -0
  7. data/Gemfile.lock +34 -0
  8. data/LICENSE +5 -4
  9. data/README.textile +54 -0
  10. data/Rakefile +15 -13
  11. data/bunny.gemspec +42 -61
  12. data/examples/simple_08.rb +4 -2
  13. data/examples/simple_09.rb +4 -2
  14. data/examples/simple_ack_08.rb +3 -1
  15. data/examples/simple_ack_09.rb +3 -1
  16. data/examples/simple_consumer_08.rb +4 -2
  17. data/examples/simple_consumer_09.rb +4 -2
  18. data/examples/simple_fanout_08.rb +3 -1
  19. data/examples/simple_fanout_09.rb +3 -1
  20. data/examples/simple_headers_08.rb +5 -3
  21. data/examples/simple_headers_09.rb +5 -3
  22. data/examples/simple_publisher_08.rb +3 -1
  23. data/examples/simple_publisher_09.rb +3 -1
  24. data/examples/simple_topic_08.rb +5 -3
  25. data/examples/simple_topic_09.rb +5 -3
  26. data/ext/amqp-0.8.json +616 -0
  27. data/ext/amqp-0.9.1.json +388 -0
  28. data/ext/config.yml +4 -0
  29. data/ext/qparser.rb +463 -0
  30. data/lib/bunny.rb +88 -66
  31. data/lib/bunny/channel08.rb +38 -38
  32. data/lib/bunny/channel09.rb +37 -37
  33. data/lib/bunny/client08.rb +184 -206
  34. data/lib/bunny/client09.rb +277 -363
  35. data/lib/bunny/consumer.rb +35 -0
  36. data/lib/bunny/exchange08.rb +37 -41
  37. data/lib/bunny/exchange09.rb +106 -124
  38. data/lib/bunny/queue08.rb +216 -202
  39. data/lib/bunny/queue09.rb +256 -326
  40. data/lib/bunny/subscription08.rb +30 -29
  41. data/lib/bunny/subscription09.rb +84 -83
  42. data/lib/bunny/version.rb +5 -0
  43. data/lib/qrack/amq-client-url.rb +165 -0
  44. data/lib/qrack/channel.rb +19 -17
  45. data/lib/qrack/client.rb +152 -151
  46. data/lib/qrack/errors.rb +5 -0
  47. data/lib/qrack/protocol/protocol08.rb +132 -130
  48. data/lib/qrack/protocol/protocol09.rb +133 -131
  49. data/lib/qrack/protocol/spec08.rb +2 -0
  50. data/lib/qrack/protocol/spec09.rb +2 -0
  51. data/lib/qrack/qrack08.rb +7 -10
  52. data/lib/qrack/qrack09.rb +7 -10
  53. data/lib/qrack/queue.rb +27 -40
  54. data/lib/qrack/subscription.rb +102 -101
  55. data/lib/qrack/transport/buffer08.rb +266 -264
  56. data/lib/qrack/transport/buffer09.rb +268 -264
  57. data/lib/qrack/transport/frame08.rb +13 -11
  58. data/lib/qrack/transport/frame09.rb +9 -7
  59. data/spec/spec_08/bunny_spec.rb +48 -45
  60. data/spec/spec_08/connection_spec.rb +10 -7
  61. data/spec/spec_08/exchange_spec.rb +145 -143
  62. data/spec/spec_08/queue_spec.rb +161 -161
  63. data/spec/spec_09/bunny_spec.rb +46 -44
  64. data/spec/spec_09/connection_spec.rb +15 -8
  65. data/spec/spec_09/exchange_spec.rb +147 -145
  66. data/spec/spec_09/queue_spec.rb +182 -184
  67. metadata +60 -41
  68. data/README.rdoc +0 -66
@@ -1,5 +1,7 @@
1
+ # encoding: utf-8
2
+
1
3
  module Bunny
2
-
4
+
3
5
  =begin rdoc
4
6
 
5
7
  === DESCRIPTION:
@@ -27,10 +29,10 @@ processing. If error occurs, _Bunny_::_ProtocolError_ is raised.
27
29
 
28
30
  ==== OPERATION:
29
31
 
30
- Passes a hash of message information to the block, if one has been supplied. The hash contains
32
+ Passes a hash of message information to the block, if one has been supplied. The hash contains
31
33
  :header, :payload and :delivery_details. The structure of the data is as follows -
32
34
 
33
- :header has instance variables -
35
+ :header has instance variables -
34
36
  @klass
35
37
  @size
36
38
  @weight
@@ -45,7 +47,7 @@ Passes a hash of message information to the block, if one has been supplied. The
45
47
  :consumer_tag
46
48
  :delivery_tag
47
49
  :redelivered
48
- :exchange
50
+ :exchange
49
51
  :routing_key
50
52
 
51
53
  If the :timeout option is specified then Qrack::ClientTimeout is raised if method times out
@@ -58,28 +60,27 @@ my_queue.subscribe(:timeout => 5) {|msg| puts msg[:payload]}
58
60
  my_queue.subscribe(:message_max => 10, :ack => true) {|msg| puts msg[:payload]}
59
61
 
60
62
  =end
61
-
62
- class Subscription < Qrack::Subscription
63
-
64
-
65
- def setup_consumer
66
- client.send_frame(
67
- Qrack::Protocol::Basic::Consume.new({ :queue => queue.name,
68
- :consumer_tag => consumer_tag,
69
- :no_ack => !ack,
70
- :exclusive => exclusive,
71
- :nowait => false }.merge(@opts))
72
- )
73
-
74
- method = client.next_method
75
-
76
- client.check_response(method, Qrack::Protocol::Basic::ConsumeOk,
77
- "Error subscribing to queue #{queue.name}")
78
-
79
- @consumer_tag = method.consumer_tag
80
-
81
- end
82
-
83
- end
84
-
85
- end
63
+
64
+ class Subscription < Bunny::Consumer
65
+
66
+ def setup_consumer
67
+ subscription_options = {
68
+ :queue => queue.name,
69
+ :consumer_tag => consumer_tag,
70
+ :no_ack => !ack,
71
+ :exclusive => exclusive,
72
+ :nowait => false
73
+ }.merge(@opts)
74
+
75
+ client.send_frame(Qrack::Protocol::Basic::Consume.new(subscription_options))
76
+
77
+ method = client.next_method
78
+
79
+ client.check_response(method, Qrack::Protocol::Basic::ConsumeOk, "Error subscribing to queue #{queue.name}")
80
+
81
+ @consumer_tag = method.consumer_tag
82
+ end
83
+
84
+ end
85
+
86
+ end
@@ -1,85 +1,86 @@
1
- module Bunny
2
-
3
- =begin rdoc
4
-
5
- === DESCRIPTION:
6
-
7
- Asks the server to start a "consumer", which is a transient request for messages from a specific
8
- queue. Consumers last as long as the channel they were created on, or until the client cancels them
9
- with an _unsubscribe_. Every time a message reaches the queue it is passed to the _blk_ for
10
- processing. If error occurs, _Bunny_::_ProtocolError_ is raised.
11
-
12
- ==== OPTIONS:
13
- * <tt>:consumer_tag => '_tag_'</tt> - Specifies the identifier for the consumer. The consumer tag is
14
- local to a connection, so two clients can use the same consumer tags. If this option is not
15
- specified a server generated name is used.
16
- * <tt>:ack => false (_default_) or true</tt> - If set to _false_, the server does not expect an
17
- acknowledgement message 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 receive one within a time specified
19
- by the server.
20
- * <tt>:exclusive => true or false (_default_)</tt> - Request exclusive consumer access, meaning
21
- only this consumer can access the queue.
22
- * <tt>:nowait => true or false (_default_)</tt> - Ignored by Bunny, always _false_.
23
- * <tt>:timeout => number of seconds - The subscribe loop will continue to wait for
24
- messages until terminated (Ctrl-C or kill command) or this timeout interval is reached.
25
- * <tt>:message_max => max number messages to process</tt> - When the required number of messages
26
- is processed subscribe loop is exited.
27
-
28
- ==== OPERATION:
29
-
30
- Passes a hash of message information to the block, if one has been supplied. The hash contains
31
- :header, :payload and :delivery_details. The structure of the data is as follows -
32
-
33
- :header has instance variables -
34
- @klass
35
- @size
36
- @weight
37
- @properties is a hash containing -
38
- :content_type
39
- :delivery_mode
40
- :priority
41
-
42
- :payload contains the message contents
1
+ # encoding: utf-8
43
2
 
44
- :delivery details is a hash containing -
45
- :consumer_tag
46
- :delivery_tag
47
- :redelivered
48
- :exchange
49
- :routing_key
50
-
51
- If the :timeout option is specified then Qrack::ClientTimeout is raised if method times out
52
- waiting to receive the next message from the queue.
53
-
54
- ==== EXAMPLES
55
-
56
- my_queue.subscribe(:timeout => 5) {|msg| puts msg[:payload]}
57
-
58
- my_queue.subscribe(:message_max => 10, :ack => true) {|msg| puts msg[:payload]}
59
-
60
- =end
61
-
62
- class Subscription09 < Qrack::Subscription
63
-
64
- def setup_consumer
65
- client.send_frame(
66
- Qrack::Protocol09::Basic::Consume.new({ :deprecated_ticket => 0,
67
- :queue => queue.name,
68
- :consumer_tag => consumer_tag,
69
- :no_ack => !ack,
70
- :exclusive => exclusive,
71
- :nowait => false}.merge(@opts))
72
- )
73
-
74
- method = client.next_method
75
-
76
- client.check_response(method, Qrack::Protocol09::Basic::ConsumeOk,
77
- "Error subscribing to queue #{queue.name}")
3
+ module Bunny
78
4
 
79
- @consumer_tag = method.consumer_tag
80
-
81
- end
82
-
83
- end
84
-
85
- end
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 Qrack::ClientTimeout is raised if method times out
58
+ # waiting to receive the next message from the queue.
59
+ #
60
+ # @example
61
+ # my_queue.subscribe(timeout: 5) { |msg| puts msg[:payload] }
62
+ # my_queue.subscribe(message_max: 10, ack: true) { |msg| puts msg[:payload] }
63
+ class Subscription09 < Bunny::Consumer
64
+
65
+ def setup_consumer
66
+ subscription_options = {
67
+ :deprecated_ticket => 0,
68
+ :queue => queue.name,
69
+ :consumer_tag => consumer_tag,
70
+ :no_ack => !ack,
71
+ :exclusive => exclusive,
72
+ :nowait => false
73
+ }.merge(@opts)
74
+
75
+ client.send_frame(Qrack::Protocol09::Basic::Consume.new(subscription_options))
76
+
77
+ method = client.next_method
78
+
79
+ client.check_response(method, Qrack::Protocol09::Basic::ConsumeOk, "Error subscribing to queue #{queue.name}")
80
+
81
+ @consumer_tag = method.consumer_tag
82
+ end
83
+
84
+ end
85
+
86
+ end
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+
3
+ module Bunny
4
+ VERSION = "0.7"
5
+ end
@@ -0,0 +1,165 @@
1
+ # encoding: utf-8
2
+
3
+ ################################################################
4
+ # DO NOT EDIT THIS FILE ! #
5
+ # The file comes from https://github.com/ruby-amqp/amq-client, #
6
+ # it's located in lib/amq/client/settings.rb, so if you want #
7
+ # to make some changes, please do them in the amq-client repo. #
8
+ ################################################################
9
+
10
+ # TODO: When we start to work on porting Bunny on AMQ Client,
11
+ # this file will become obsolete.
12
+
13
+ require "uri"
14
+
15
+ module AMQ
16
+ module Client
17
+ # @see AMQ::Client::Settings.configure
18
+ module Settings
19
+ # @private
20
+ AMQP_PORTS = {"amqp" => 5672, "amqps" => 5671}.freeze
21
+
22
+ # @private
23
+ AMQPS = "amqps".freeze
24
+
25
+ # Default connection settings used by AMQ clients
26
+ #
27
+ # @see AMQ::Client::Settings.configure
28
+ def self.default
29
+ @default ||= {
30
+ # server
31
+ :host => "127.0.0.1",
32
+ :port => AMQ::Protocol::DEFAULT_PORT,
33
+
34
+ # login
35
+ :user => "guest",
36
+ :pass => "guest",
37
+ :vhost => "/",
38
+
39
+ # connection timeout
40
+ :timeout => nil,
41
+
42
+ # logging
43
+ :logging => false,
44
+
45
+ # ssl
46
+ :ssl => false,
47
+
48
+ # broker
49
+ # if you want to load broker-specific extensions
50
+ :broker => nil,
51
+
52
+ :frame_max => 131072
53
+ }
54
+ end
55
+
56
+
57
+ def self.client_properties
58
+ @client_properties ||= {
59
+ :platform => ::RUBY_DESCRIPTION,
60
+ :product => "AMQ Client",
61
+ :information => "http://github.com/ruby-amqp/amq-client",
62
+ :version => AMQ::Client::VERSION
63
+ }
64
+ end
65
+
66
+
67
+ # Merges given configuration parameters with defaults and returns
68
+ # the result.
69
+ #
70
+ # @param [Hash] Configuration parameters to use.
71
+ #
72
+ # @option settings [String] :host ("127.0.0.1") Hostname AMQ broker runs on.
73
+ # @option settings [String] :port (5672) Port AMQ broker listens on.
74
+ # @option settings [String] :vhost ("/") Virtual host to use.
75
+ # @option settings [String] :user ("guest") Username to use for authentication.
76
+ # @option settings [String] :pass ("guest") Password to use for authentication.
77
+ # @option settings [String] :ssl (false) Should be use TLS (SSL) for connection?
78
+ # @option settings [String] :timeout (nil) Connection timeout.
79
+ # @option settings [String] :logging (false) Turns logging on or off.
80
+ # @option settings [String] :broker (nil) Broker name (use if you intend to use broker-specific features).
81
+ # @option settings [Fixnum] :frame_max (131072) Maximum frame size to use. If broker cannot support frames this large, broker's maximum value will be used instead.
82
+ #
83
+ # @return [Hash] Merged configuration parameters.
84
+ def self.configure(settings = nil)
85
+ case settings
86
+ when Hash then
87
+ if username = settings.delete(:username)
88
+ settings[:user] ||= username
89
+ end
90
+
91
+ if password = settings.delete(:password)
92
+ settings[:pass] ||= password
93
+ end
94
+
95
+
96
+ self.default.merge(settings)
97
+ when String then
98
+ settings = self.parse_amqp_url(settings)
99
+ self.default.merge(settings)
100
+ when NilClass then
101
+ self.default
102
+ end
103
+ end
104
+
105
+ # Parses AMQP connection URI and returns its components as a hash.
106
+ #
107
+ # h2. vhost naming schemes
108
+ #
109
+ # It is convenient to be able to specify the AMQP connection
110
+ # parameters as a URI string, and various "amqp" URI schemes
111
+ # exist. Unfortunately, there is no standard for these URIs, so
112
+ # while the schemes share the basic idea, they differ in some
113
+ # details. This implementation aims to encourage URIs that work
114
+ # as widely as possible.
115
+ #
116
+ # The URI scheme should be "amqp", or "amqps" if SSL is required.
117
+ #
118
+ # The host, port, username and password are represented in the
119
+ # authority component of the URI in the same way as in http URIs.
120
+ #
121
+ # The vhost is obtained from the first segment of the path, with the
122
+ # leading slash removed. The path should contain only a single
123
+ # segment (i.e, the only slash in it should be the leading one).
124
+ # If the vhost is to include slashes or other reserved URI
125
+ # characters, these should be percent-escaped.
126
+ #
127
+ # @example How vhost is parsed
128
+ #
129
+ # AMQ::Client::Settings.parse_amqp_url("amqp://dev.rabbitmq.com") # => vhost is nil, so default (/) will be used
130
+ # AMQ::Client::Settings.parse_amqp_url("amqp://dev.rabbitmq.com/") # => vhost is an empty string
131
+ # AMQ::Client::Settings.parse_amqp_url("amqp://dev.rabbitmq.com/%2Fvault") # => vhost is /vault
132
+ # AMQ::Client::Settings.parse_amqp_url("amqp://dev.rabbitmq.com/production") # => vhost is production
133
+ # AMQ::Client::Settings.parse_amqp_url("amqp://dev.rabbitmq.com/a.b.c") # => vhost is a.b.c
134
+ # AMQ::Client::Settings.parse_amqp_url("amqp://dev.rabbitmq.com/foo/bar") # => ArgumentError
135
+ #
136
+ #
137
+ # @param [String] connection_string AMQP connection URI, à la JDBC connection string. For example: amqp://bus.megacorp.internal:5877.
138
+ # @return [Hash] Connection parameters (:username, :password, :vhost, :host, :port, :ssl)
139
+ #
140
+ # @raise [ArgumentError] When connection URI schema is not amqp or amqps, or the path contains multiple segments
141
+ #
142
+ # @see http://bit.ly/ks8MXK Connecting to The Broker documentation guide
143
+ # @api public
144
+ def self.parse_amqp_url(connection_string)
145
+ uri = URI.parse(connection_string)
146
+ raise ArgumentError.new("Connection URI must use amqp or amqps schema (example: amqp://bus.megacorp.internal:5766), learn more at http://bit.ly/ks8MXK") unless %w{amqp amqps}.include?(uri.scheme)
147
+
148
+ opts = {}
149
+
150
+ opts[:scheme] = uri.scheme
151
+ opts[:user] = URI.unescape(uri.user) if uri.user
152
+ opts[:pass] = URI.unescape(uri.password) if uri.password
153
+ opts[:host] = uri.host if uri.host
154
+ opts[:port] = uri.port || AMQ::Client::Settings::AMQP_PORTS[uri.scheme]
155
+ opts[:ssl] = uri.scheme == AMQ::Client::Settings::AMQPS
156
+ if uri.path =~ %r{^/(.*)}
157
+ raise ArgumentError.new("#{uri} has multiple-segment path; please percent-encode any slashes in the vhost name (e.g. /production => %2Fproduction). Learn more at http://bit.ly/amqp-gem-and-connection-uris") if $1.index('/')
158
+ opts[:vhost] = URI.unescape($1)
159
+ end
160
+
161
+ opts
162
+ end
163
+ end
164
+ end
165
+ end
@@ -1,18 +1,20 @@
1
+ # encoding: utf-8
2
+
1
3
  module Qrack
2
- # Channel ancestor class
3
- class Channel
4
-
5
- attr_accessor :number, :active, :frame_buffer
6
- attr_reader :client
7
-
8
- def initialize(client)
9
- @frame_buffer = []
10
- @client = client
11
- @number = client.channels.size
12
- @active = false
13
- client.channels[@number] = self
14
- end
15
-
16
- end
17
-
18
- end
4
+ # Channel ancestor class
5
+ class Channel
6
+
7
+ attr_accessor :number, :active, :frame_buffer
8
+ attr_reader :client
9
+
10
+ def initialize(client)
11
+ @frame_buffer = []
12
+ @client = client
13
+ @number = client.channels.size
14
+ @active = false
15
+ client.channels[@number] = self
16
+ end
17
+
18
+ end
19
+
20
+ end