amqp 0.9.10 → 1.0.0.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.travis.yml +0 -3
- data/CHANGELOG +4 -0
- data/Gemfile +1 -0
- data/README.md +72 -81
- data/amqp.gemspec +14 -5
- data/docs/08Migration.textile +0 -4
- data/docs/AMQP091ModelExplained.textile +0 -5
- data/docs/Bindings.textile +0 -4
- data/docs/Clustering.textile +0 -4
- data/docs/ConnectingToTheBroker.textile +1 -5
- data/docs/ConnectionEncryptionWithTLS.textile +0 -4
- data/docs/DocumentationGuidesIndex.textile +0 -4
- data/docs/Durability.textile +0 -4
- data/docs/ErrorHandling.textile +40 -106
- data/docs/Exchanges.textile +0 -4
- data/docs/GettingStarted.textile +6 -10
- data/docs/PatternsAndUseCases.textile +1 -4
- data/docs/Queues.textile +0 -4
- data/docs/RabbitMQVersions.textile +0 -4
- data/docs/RunningTests.textile +0 -4
- data/docs/TestingWithEventedSpec.textile +0 -4
- data/docs/Troubleshooting.textile +0 -4
- data/docs/VendorSpecificExtensions.textile +0 -4
- data/examples/error_handling/hello_world_producer.rb +1 -1
- data/examples/issues/issue_121.rb +23 -0
- data/examples/patterns/request_reply/client.rb +2 -1
- data/examples/patterns/request_reply/server.rb +1 -0
- data/examples/publishing/returned_messages.rb +1 -1
- data/lib/amqp.rb +0 -7
- data/lib/amqp/channel.rb +15 -33
- data/lib/amqp/client.rb +2 -2
- data/lib/amqp/compatibility/ruby187_patchlevel_check.rb +4 -4
- data/lib/amqp/connection.rb +0 -1
- data/lib/amqp/consumer.rb +2 -2
- data/lib/amqp/exceptions.rb +1 -10
- data/lib/amqp/exchange.rb +5 -5
- data/lib/amqp/queue.rb +23 -47
- data/lib/amqp/session.rb +4 -4
- data/lib/amqp/version.rb +1 -1
- data/spec/integration/basic_get_spec.rb +24 -80
- data/spec/integration/basic_return_spec.rb +3 -3
- data/spec/integration/channel_level_exception_with_multiple_channels_spec.rb +1 -0
- data/spec/integration/exchange_declaration_spec.rb +102 -71
- data/spec/integration/extensions/rabbitmq/publisher_confirmations_spec.rb +17 -1
- data/spec/integration/fanout_exchange_routing_spec.rb +1 -1
- data/spec/integration/immediate_messages_spec.rb +59 -0
- data/spec/integration/multiple_consumers_per_queue_spec.rb +101 -39
- data/spec/integration/queue_redeclaration_with_incompatible_attributes_spec.rb +12 -25
- data/spec/integration/regressions/concurrent_publishing_on_the_same_channel_spec.rb +1 -1
- data/spec/integration/reply_queue_communication_spec.rb +2 -1
- data/spec/integration/store_and_forward_spec.rb +9 -6
- data/spec/integration/topic_subscription_spec.rb +4 -5
- data/spec/spec_helper.rb +2 -8
- data/spec/unit/amqp/connection_spec.rb +1 -3
- metadata +112 -116
- data/examples/deprecated/default_thread_local_channel_instance.rb +0 -34
- data/examples/legacy/ack.rb +0 -70
- data/examples/legacy/callbacks.rb +0 -45
- data/examples/legacy/clock.rb +0 -74
- data/examples/legacy/hashtable.rb +0 -60
- data/examples/legacy/logger.rb +0 -92
- data/examples/legacy/multiclock.rb +0 -56
- data/examples/legacy/pingpong.rb +0 -51
- data/examples/legacy/primes-simple.rb +0 -29
- data/examples/legacy/primes.rb +0 -74
- data/examples/legacy/stocks.rb +0 -59
- data/lib/amqp/deprecated/fork.rb +0 -17
- data/lib/amqp/deprecated/logger.rb +0 -100
- data/lib/amqp/deprecated/mq.rb +0 -22
- data/lib/amqp/deprecated/rpc.rb +0 -169
- data/lib/amqp/ext/em.rb +0 -3
- data/lib/amqp/ext/emfork.rb +0 -72
- data/lib/amqp/logger.rb +0 -19
- data/lib/amqp/rpc.rb +0 -20
- data/lib/mq.rb +0 -35
- data/lib/mq/logger.rb +0 -4
- data/lib/mq/rpc.rb +0 -4
- data/spec/integration/remove_individual_binding_spec.rb +0 -51
data/lib/amqp/deprecated/fork.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require "amqp/ext/em"
|
4
|
-
|
5
|
-
module AMQP
|
6
|
-
# @deprecated
|
7
|
-
# @private
|
8
|
-
def self.fork(workers)
|
9
|
-
EM.fork(workers) do
|
10
|
-
# clean up globals in the fork
|
11
|
-
Thread.current[:mq] = nil
|
12
|
-
AMQP.instance_variable_set('@conn', nil)
|
13
|
-
|
14
|
-
yield
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,100 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module AMQP
|
4
|
-
# @private
|
5
|
-
class Logger
|
6
|
-
def initialize(*args, &block)
|
7
|
-
opts = args.pop if args.last.is_a? Hash
|
8
|
-
opts ||= {}
|
9
|
-
|
10
|
-
printer(block) if block
|
11
|
-
|
12
|
-
@prop = opts
|
13
|
-
@tags = ([:timestamp] + args).uniq
|
14
|
-
end
|
15
|
-
|
16
|
-
attr_reader :prop
|
17
|
-
alias :base :prop
|
18
|
-
|
19
|
-
def log(severity, *args)
|
20
|
-
opts = args.pop if args.last.is_a? Hash and args.size != 1
|
21
|
-
opts ||= {}
|
22
|
-
opts = @prop.clone.update(opts)
|
23
|
-
|
24
|
-
data = args.shift
|
25
|
-
|
26
|
-
data = {:type => :exception,
|
27
|
-
:name => data.class.to_s.intern,
|
28
|
-
:backtrace => data.backtrace,
|
29
|
-
:message => data.message} if data.is_a? Exception
|
30
|
-
|
31
|
-
(@tags + args).each do |tag|
|
32
|
-
tag = tag.to_sym
|
33
|
-
case tag
|
34
|
-
when :timestamp
|
35
|
-
opts.update :timestamp => Time.now
|
36
|
-
when :hostname
|
37
|
-
@hostname ||= { :hostname => `hostname`.strip }
|
38
|
-
opts.update @hostname
|
39
|
-
when :process
|
40
|
-
@process_id ||= { :process_id => Process.pid,
|
41
|
-
:process_name => $0,
|
42
|
-
:process_parent_id => Process.ppid,
|
43
|
-
:thread_id => Thread.current.object_id }
|
44
|
-
opts.update :process => @process_id
|
45
|
-
else
|
46
|
-
(opts[:tags] ||= []) << tag
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
opts.update(:severity => severity,
|
51
|
-
:msg => data)
|
52
|
-
|
53
|
-
print(opts)
|
54
|
-
unless Logger.disabled?
|
55
|
-
AMQP::Channel.new.fanout('logging', :durable => true).publish Marshal.dump(opts)
|
56
|
-
end
|
57
|
-
|
58
|
-
opts
|
59
|
-
end
|
60
|
-
alias :method_missing :log
|
61
|
-
|
62
|
-
def print(data = nil, &block)
|
63
|
-
if block
|
64
|
-
@printer = block
|
65
|
-
elsif data.is_a? Proc
|
66
|
-
@printer = data
|
67
|
-
elsif data
|
68
|
-
(pr = @printer || self.class.printer) and pr.call(data)
|
69
|
-
else
|
70
|
-
@printer
|
71
|
-
end
|
72
|
-
end
|
73
|
-
alias :printer :print
|
74
|
-
|
75
|
-
def self.printer &block
|
76
|
-
@printer = block if block
|
77
|
-
@printer
|
78
|
-
end
|
79
|
-
|
80
|
-
def self.disabled?
|
81
|
-
!!@disabled
|
82
|
-
end
|
83
|
-
|
84
|
-
def self.enable
|
85
|
-
@disabled = false
|
86
|
-
end
|
87
|
-
|
88
|
-
def self.disable
|
89
|
-
@disabled = true
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
|
95
|
-
require "amqp/deprecated/mq"
|
96
|
-
class MQ
|
97
|
-
# @note This class will be removed before 1.0 release.
|
98
|
-
# @deprecated
|
99
|
-
class Logger < ::AMQP::Logger; end
|
100
|
-
end
|
data/lib/amqp/deprecated/mq.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
# Alias for AMQP::Channel.
|
4
|
-
#
|
5
|
-
# @note This class will be removed before 1.0 release.
|
6
|
-
# @deprecated
|
7
|
-
class MQ < AMQP::Channel; end
|
8
|
-
|
9
|
-
|
10
|
-
class MQ
|
11
|
-
# Alias for AMQP::Exchange.
|
12
|
-
#
|
13
|
-
# @note This class will be removed before 1.0 release.
|
14
|
-
# @deprecated
|
15
|
-
class Exchange < ::AMQP::Exchange; end
|
16
|
-
|
17
|
-
# Alias for AMQP::Queue.
|
18
|
-
#
|
19
|
-
# @note This class will be removed before 1.0 release.
|
20
|
-
# @deprecated
|
21
|
-
class Queue < ::AMQP::Queue; end
|
22
|
-
end
|
data/lib/amqp/deprecated/rpc.rb
DELETED
@@ -1,169 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module AMQP
|
4
|
-
if defined?(BasicObject)
|
5
|
-
# @private
|
6
|
-
class BlankSlate < BasicObject; end
|
7
|
-
else
|
8
|
-
# @private
|
9
|
-
class BlankSlate
|
10
|
-
instance_methods.each { |m| undef_method m unless m =~ /^__/ }
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
|
15
|
-
# Basic RPC (remote procedure call) facility.
|
16
|
-
#
|
17
|
-
# Needs more detail and explanation.
|
18
|
-
#
|
19
|
-
# EM.run do
|
20
|
-
# server = AMQP::Channel.new.rpc('hash table node', Hash)
|
21
|
-
#
|
22
|
-
# client = AMQP::Channel.new.rpc('hash table node')
|
23
|
-
# client[:now] = Time.now
|
24
|
-
# client[:one] = 1
|
25
|
-
#
|
26
|
-
# client.values do |res|
|
27
|
-
# p 'client', :values => res
|
28
|
-
# end
|
29
|
-
#
|
30
|
-
# client.keys do |res|
|
31
|
-
# p 'client', :keys => res
|
32
|
-
# EM.stop_event_loop
|
33
|
-
# end
|
34
|
-
# end
|
35
|
-
#
|
36
|
-
#
|
37
|
-
# @note This class will be removed before 1.0 release.
|
38
|
-
# @deprecated
|
39
|
-
# @private
|
40
|
-
class RPC < ::AMQP::BlankSlate
|
41
|
-
|
42
|
-
#
|
43
|
-
# API
|
44
|
-
#
|
45
|
-
|
46
|
-
|
47
|
-
attr_reader :name
|
48
|
-
|
49
|
-
# Takes a channel, queue and optional object.
|
50
|
-
#
|
51
|
-
# The optional object may be a class name, module name or object
|
52
|
-
# instance. When given a class or module name, the object is instantiated
|
53
|
-
# during this setup. The passed queue is automatically subscribed to so
|
54
|
-
# it passes all messages (and their arguments) to the object.
|
55
|
-
#
|
56
|
-
# Marshalling and unmarshalling the objects is handled internally. This
|
57
|
-
# marshalling is subject to the same restrictions as defined in the
|
58
|
-
# {http://ruby-doc.org/core/classes/Marshal.html Marshal} standard
|
59
|
-
# library. See that documentation for further reference.
|
60
|
-
#
|
61
|
-
# When the optional object is not passed, the returned rpc reference is
|
62
|
-
# used to send messages and arguments to the queue. See #method_missing
|
63
|
-
# which does all of the heavy lifting with the proxy. Some client
|
64
|
-
# elsewhere must call this method *with* the optional block so that
|
65
|
-
# there is a valid destination. Failure to do so will just enqueue
|
66
|
-
# marshalled messages that are never consumed.
|
67
|
-
#
|
68
|
-
def initialize(channel, queue, obj = nil)
|
69
|
-
@name = queue
|
70
|
-
@channel = channel
|
71
|
-
@channel.register_rpc(self)
|
72
|
-
|
73
|
-
if @obj = normalize(obj)
|
74
|
-
@delegate = Server.new(channel, queue, @obj)
|
75
|
-
else
|
76
|
-
@delegate = Client.new(channel, queue)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
|
81
|
-
def client?
|
82
|
-
@obj.nil?
|
83
|
-
end
|
84
|
-
|
85
|
-
def server?
|
86
|
-
!client?
|
87
|
-
end
|
88
|
-
|
89
|
-
|
90
|
-
def method_missing(selector, *args, &block)
|
91
|
-
@delegate.__send__(selector, *args, &block)
|
92
|
-
end
|
93
|
-
|
94
|
-
|
95
|
-
# @private
|
96
|
-
class Client
|
97
|
-
attr_accessor :identifier
|
98
|
-
|
99
|
-
def initialize(channel, server_queue_name)
|
100
|
-
@channel = channel
|
101
|
-
@exchange = AMQP::Exchange.default(@channel)
|
102
|
-
@server_queue_name = server_queue_name
|
103
|
-
|
104
|
-
@handlers = Hash.new
|
105
|
-
@queue = channel.queue("__amqp_gem_rpc_client_#{rand(1_000_000)}", :auto_delete => true)
|
106
|
-
|
107
|
-
@queue.subscribe do |header, payload|
|
108
|
-
*response_args = Marshal.load(payload)
|
109
|
-
handler = @handlers[header.message_id]
|
110
|
-
|
111
|
-
handler.call(*response_args)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
def method_missing(selector, *args, &block)
|
116
|
-
@channel.once_open do
|
117
|
-
message_id = "message_identifier_#{rand(1_000_000)}"
|
118
|
-
|
119
|
-
if block
|
120
|
-
@handlers[message_id] = block
|
121
|
-
@exchange.publish(Marshal.dump([selector, *args]), :routing_key => @server_queue_name, :reply_to => @queue.name, :message_id => message_id)
|
122
|
-
else
|
123
|
-
@exchange.publish(Marshal.dump([selector, *args]), :routing_key => @server_queue_name, :message_id => message_id)
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end # Client
|
128
|
-
|
129
|
-
# @private
|
130
|
-
class Server
|
131
|
-
def initialize(channel, queue_name, impl)
|
132
|
-
@channel = channel
|
133
|
-
@exchange = AMQP::Exchange.default(@channel)
|
134
|
-
@queue = @channel.queue(queue_name)
|
135
|
-
@impl = impl
|
136
|
-
|
137
|
-
@handlers = Hash.new
|
138
|
-
@id = "client_identifier_#{rand(1_000_000)}"
|
139
|
-
|
140
|
-
@queue.subscribe(:ack => true) do |header, payload|
|
141
|
-
selector, *args = Marshal.load(payload)
|
142
|
-
result = @impl.__send__(selector, *args)
|
143
|
-
|
144
|
-
respond_to(header, result) if header.to_hash[:reply_to]
|
145
|
-
header.ack
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
def respond_to(header, result)
|
150
|
-
@exchange.publish(Marshal.dump(result), :message_id => header.message_id, :routing_key => header.reply_to)
|
151
|
-
end
|
152
|
-
end # Server
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
protected
|
157
|
-
|
158
|
-
def normalize(input)
|
159
|
-
case input
|
160
|
-
when ::Class
|
161
|
-
input.new
|
162
|
-
when ::Module
|
163
|
-
(::Class.new do include(obj) end).new
|
164
|
-
else
|
165
|
-
input
|
166
|
-
end
|
167
|
-
end
|
168
|
-
end # RPC
|
169
|
-
end # AMQP
|
data/lib/amqp/ext/em.rb
DELETED
data/lib/amqp/ext/emfork.rb
DELETED
@@ -1,72 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
# @private
|
4
|
-
EMFORK = $0 == __FILE__
|
5
|
-
|
6
|
-
if EMFORK
|
7
|
-
require 'rubygems'
|
8
|
-
end
|
9
|
-
|
10
|
-
require 'eventmachine'
|
11
|
-
|
12
|
-
# helper to fork off EM reactors
|
13
|
-
# @private
|
14
|
-
def EM.fork num = 1, &blk
|
15
|
-
unless @forks
|
16
|
-
trap('CHLD') {
|
17
|
-
pid = Process.wait
|
18
|
-
p [:pid, pid, :died] if EMFORK
|
19
|
-
block = @forks.delete(pid)
|
20
|
-
EM.fork(1, &block)
|
21
|
-
}
|
22
|
-
|
23
|
-
trap('EXIT') {
|
24
|
-
p [:pid, Process.pid, :exit] if EMFORK
|
25
|
-
@forks.keys.each { |pid|
|
26
|
-
p [:pid, Process.pid, :killing, pid] if EMFORK
|
27
|
-
Process.kill('USR1', pid)
|
28
|
-
}
|
29
|
-
}
|
30
|
-
|
31
|
-
@forks = {}
|
32
|
-
end
|
33
|
-
|
34
|
-
num.times do
|
35
|
-
pid = EM.fork_reactor do
|
36
|
-
p [:pid, Process.pid, :started] if EMFORK
|
37
|
-
|
38
|
-
trap('USR1') { EM.stop_event_loop }
|
39
|
-
trap('CHLD') {}
|
40
|
-
trap('EXIT') {}
|
41
|
-
|
42
|
-
blk.call
|
43
|
-
end
|
44
|
-
|
45
|
-
@forks[pid] = blk
|
46
|
-
p [:children, EM.forks] if EMFORK
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
# @private
|
51
|
-
def EM.forks
|
52
|
-
@forks ? @forks.keys : []
|
53
|
-
end
|
54
|
-
|
55
|
-
if EMFORK
|
56
|
-
p 'starting reactor'
|
57
|
-
|
58
|
-
trap('INT') { EM.stop_event_loop }
|
59
|
-
|
60
|
-
EM.run {
|
61
|
-
p [:parent, Process.pid]
|
62
|
-
|
63
|
-
EM.fork(2) {
|
64
|
-
EM.add_periodic_timer(1) do
|
65
|
-
p [:fork, Process.pid, :ping]
|
66
|
-
end
|
67
|
-
}
|
68
|
-
|
69
|
-
}
|
70
|
-
|
71
|
-
p 'reactor stopped'
|
72
|
-
end
|
data/lib/amqp/logger.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
$stdout.puts <<-MESSAGE
|
4
|
-
-------------------------------------------------------------------------------------
|
5
|
-
DEPRECATION WARNING!
|
6
|
-
|
7
|
-
Use of amqp/logger.rb is deprecated. Instead of
|
8
|
-
|
9
|
-
require "amqp/logger"
|
10
|
-
|
11
|
-
please use
|
12
|
-
|
13
|
-
require "amqp/deprecated/logger"
|
14
|
-
|
15
|
-
|
16
|
-
Both amqp/logger.rb and AMQP::Logger will be REMOVED before 1.0 release.
|
17
|
-
MESSAGE
|
18
|
-
|
19
|
-
require "amqp/deprecated/logger"
|
data/lib/amqp/rpc.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
$stdout.puts <<-MESSAGE
|
4
|
-
-------------------------------------------------------------------------------------
|
5
|
-
DEPRECATION WARNING!
|
6
|
-
|
7
|
-
Use of amqp/rpc.rb is deprecated. Instead of
|
8
|
-
|
9
|
-
require "amqp/rpc"
|
10
|
-
|
11
|
-
please use
|
12
|
-
|
13
|
-
require "amqp/deprecated/rpc"
|
14
|
-
|
15
|
-
|
16
|
-
Both amqp/rpc.rb and AMQP::RPC implementation will be REMOVED before 1.0 release.
|
17
|
-
If you need RPC, we recommend the rpc gem (see https://github.com/ruby-amqp/rpc).
|
18
|
-
MESSAGE
|
19
|
-
|
20
|
-
require "amqp/deprecated/rpc"
|
data/lib/mq.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
$stdout.puts <<-MESSAGE
|
4
|
-
-------------------------------------------------------------------------------------
|
5
|
-
DEPRECATION WARNING!
|
6
|
-
|
7
|
-
Use of mq.rb is deprecated. Instead of
|
8
|
-
|
9
|
-
require "mq"
|
10
|
-
|
11
|
-
please use
|
12
|
-
|
13
|
-
require "amqp"
|
14
|
-
|
15
|
-
|
16
|
-
mq.rb will be REMOVED in AMQP gem version 1.0.
|
17
|
-
|
18
|
-
Why is it deprecated? Because it was a poor name choice all along. We better not
|
19
|
-
release 1.0 with it. Both mq.rb and MQ class step away from AMQP terminology and
|
20
|
-
make 8 out of 10 engineers think it has something to do with AMQP queues (in fact,
|
21
|
-
MQ should have been called Channel all along). No other AMQP client library we know
|
22
|
-
of invents its own terminology when it comes to AMQP entities, and amqp gem shouldn't,
|
23
|
-
too.
|
24
|
-
|
25
|
-
Learn more at http://bit.ly/amqp-gem-080-migration, all documentation guides are at
|
26
|
-
http://bit.ly/amqp-gem-docs, AMQP Model Explained at http://bit.ly/amqp-model-explained.
|
27
|
-
|
28
|
-
We are also in #rabbitmq on irc.freenode.net.
|
29
|
-
|
30
|
-
Thank you for understanding. AMQP gem maintainers team.
|
31
|
-
|
32
|
-
-------------------------------------------------------------------------------------
|
33
|
-
MESSAGE
|
34
|
-
|
35
|
-
require "amqp"
|