amqp 0.7.5 → 0.8.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -4
- data/.travis.yml +3 -5
- data/.yardopts +6 -0
- data/CHANGELOG +26 -7
- data/Gemfile +15 -7
- data/README.textile +216 -0
- data/Rakefile +0 -6
- data/amqp.gemspec +14 -4
- data/bin/jenkins.sh +27 -0
- data/bin/set_test_suite_realms_up.sh +16 -2
- data/docs/VendorSpecificExtensions.textile +32 -0
- data/examples/extensions/rabbitmq/publisher_confirmations_with_transient_messages.rb +53 -0
- data/examples/hello_world.rb +29 -0
- data/examples/real-world/task-queue/README.textile +3 -0
- data/examples/real-world/task-queue/consumer.rb +27 -0
- data/examples/real-world/task-queue/producer.rb +22 -0
- data/examples/various/ack.rb +70 -0
- data/examples/various/automatic_binding_for_default_direct_exchange.rb +53 -0
- data/examples/various/basic_get.rb +65 -0
- data/examples/various/callbacks.rb +45 -0
- data/examples/various/clock.rb +74 -0
- data/examples/various/declare_a_queue_without_assignment.rb +46 -0
- data/examples/various/declare_an_exchange_without_assignment.rb +46 -0
- data/examples/various/hashtable.rb +60 -0
- data/examples/{logger.rb → various/logger.rb} +9 -7
- data/examples/{multiclock.rb → various/multiclock.rb} +15 -17
- data/examples/various/open_channel_without_assignment.rb +34 -0
- data/examples/various/pingpong.rb +53 -0
- data/examples/various/primes-simple.rb +29 -0
- data/examples/various/primes.rb +76 -0
- data/examples/various/pubsub.rb +43 -0
- data/examples/various/queue_status.rb +58 -0
- data/examples/various/stocks.rb +59 -0
- data/examples/various/weather_updates.rb +63 -0
- data/lib/amqp.rb +11 -2
- data/lib/amqp/basic_client.rb +23 -54
- data/lib/amqp/channel.rb +577 -805
- data/lib/amqp/client.rb +37 -275
- data/lib/amqp/connection.rb +165 -93
- data/lib/amqp/deprecated/fork.rb +15 -0
- data/lib/amqp/deprecated/logger.rb +99 -0
- data/lib/amqp/deprecated/mq.rb +20 -0
- data/lib/amqp/deprecated/rpc.rb +168 -0
- data/lib/amqp/exchange.rb +409 -281
- data/lib/amqp/extensions/rabbitmq.rb +1 -0
- data/lib/amqp/header.rb +41 -17
- data/lib/amqp/logger.rb +10 -84
- data/lib/amqp/queue.rb +457 -320
- data/lib/amqp/rpc.rb +11 -107
- data/lib/amqp/version.rb +1 -1
- data/lib/mq.rb +2 -1
- data/lib/mq/logger.rb +2 -0
- data/lib/mq/rpc.rb +2 -0
- data/spec/integration/authentication_spec.rb +36 -40
- data/spec/integration/automatic_binding_for_default_direct_exchange_spec.rb +3 -5
- data/spec/integration/basic_get_spec.rb +91 -0
- data/spec/integration/channel_close_spec.rb +5 -5
- data/spec/integration/exchange_declaration_spec.rb +6 -53
- data/spec/integration/extensions/basic_return_spec.rb +47 -0
- data/spec/integration/queue_declaration_spec.rb +14 -17
- data/spec/integration/queue_exclusivity_spec.rb +49 -48
- data/spec/integration/reply_queue_communication_spec.rb +6 -4
- data/spec/integration/store_and_forward_spec.rb +9 -36
- data/spec/integration/topic_subscription_spec.rb +1 -1
- data/spec/integration/workload_distribution_spec.rb +1 -0
- data/spec/spec_helper.rb +69 -43
- data/spec/unit/amqp/connection_spec.rb +27 -23
- data/tasks.rb +11 -0
- metadata +124 -95
- data/README.md +0 -156
- data/TODO +0 -30
- data/amqp.pre.gemspec +0 -6
- data/examples/ack.rb +0 -47
- data/examples/automatic_binding_for_default_direct_exchange.rb +0 -65
- data/examples/callbacks.rb +0 -40
- data/examples/clock.rb +0 -65
- data/examples/default_channel.rb +0 -19
- data/examples/hashtable.rb +0 -61
- data/examples/immediately_bind_a_server_named_queue.rb +0 -38
- data/examples/internal.rb +0 -51
- data/examples/issues/issue_75.rb +0 -21
- data/examples/issues/issue_94.rb +0 -23
- data/examples/pingpong.rb +0 -54
- data/examples/pop.rb +0 -45
- data/examples/primes-simple.rb +0 -21
- data/examples/primes.rb +0 -101
- data/examples/simple.rb +0 -81
- data/examples/stocks.rb +0 -67
- data/gemfiles/eventmachine-pre +0 -24
- data/lib/amqp/buffer.rb +0 -272
- data/lib/amqp/collection.rb +0 -60
- data/lib/amqp/frame.rb +0 -68
- data/lib/amqp/protocol.rb +0 -163
- data/lib/amqp/server.rb +0 -101
- data/lib/amqp/spec.rb +0 -832
- data/protocol/amqp-0.8.json +0 -617
- data/protocol/amqp-0.8.xml +0 -3908
- data/protocol/codegen.rb +0 -175
- data/protocol/doc.txt +0 -281
- data/research/api.rb +0 -52
- data/research/primes-forked.rb +0 -65
- data/research/primes-processes.rb +0 -137
- data/research/primes-threaded.rb +0 -51
- data/spec/integration/queue_status_spec.rb +0 -44
- data/spec/unit/amqp/buffer_spec.rb +0 -178
- data/spec/unit/amqp/client_spec.rb +0 -102
- data/spec/unit/amqp/collection_spec.rb +0 -144
- data/spec/unit/amqp/frame_spec.rb +0 -60
- data/spec/unit/amqp/protocol_spec.rb +0 -51
data/examples/issues/issue_94.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: utf-8
|
3
|
-
|
4
|
-
require "bundler"
|
5
|
-
Bundler.setup
|
6
|
-
|
7
|
-
$:.unshift(File.expand_path("../../../lib", __FILE__))
|
8
|
-
|
9
|
-
require "amqp"
|
10
|
-
|
11
|
-
puts "Running amqp gem #{AMQP::VERSION}"
|
12
|
-
|
13
|
-
AMQP.start(:host => '127.0.0.1') do |connection|
|
14
|
-
channel = AMQP::Channel.new(connection)
|
15
|
-
exchange = channel.direct("")
|
16
|
-
queue = channel.queue("indexer_queue", { :durable => true })
|
17
|
-
|
18
|
-
EM.add_periodic_timer(1) {
|
19
|
-
queue.status do |num_messages, num_consumers|
|
20
|
-
puts "msgs:#{num_messages}"
|
21
|
-
end
|
22
|
-
}
|
23
|
-
end
|
data/examples/pingpong.rb
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
$:.unshift(File.expand_path("../../lib", __FILE__))
|
4
|
-
require 'amqp'
|
5
|
-
|
6
|
-
AMQP.start(:host => 'localhost') do |connection|
|
7
|
-
|
8
|
-
# Send Connection.Close on Ctrl+C
|
9
|
-
trap(:INT) do
|
10
|
-
unless connection.closing?
|
11
|
-
connection.close { exit! }
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def log(*args)
|
16
|
-
p [ Time.now, *args ]
|
17
|
-
end
|
18
|
-
|
19
|
-
# AMQP.logging = true
|
20
|
-
|
21
|
-
amq = AMQP::Channel.new
|
22
|
-
EM.add_periodic_timer(1) {
|
23
|
-
puts
|
24
|
-
|
25
|
-
log :sending, 'ping'
|
26
|
-
amq.queue('one').publish('ping')
|
27
|
-
}
|
28
|
-
|
29
|
-
amq = AMQP::Channel.new
|
30
|
-
amq.queue('one').subscribe { |msg|
|
31
|
-
log 'one', :received, msg, :sending, 'pong'
|
32
|
-
amq.queue('two').publish('pong')
|
33
|
-
}
|
34
|
-
|
35
|
-
amq = AMQP::Channel.new
|
36
|
-
amq.queue('two').subscribe { |msg|
|
37
|
-
log 'two', :received, msg
|
38
|
-
}
|
39
|
-
|
40
|
-
end
|
41
|
-
|
42
|
-
__END__
|
43
|
-
|
44
|
-
[Sun Jul 20 03:52:24 -0700 2008, :sending, "ping"]
|
45
|
-
[Sun Jul 20 03:52:24 -0700 2008, "one", :received, "ping", :sending, "pong"]
|
46
|
-
[Sun Jul 20 03:52:24 -0700 2008, "two", :received, "pong"]
|
47
|
-
|
48
|
-
[Sun Jul 20 03:52:25 -0700 2008, :sending, "ping"]
|
49
|
-
[Sun Jul 20 03:52:25 -0700 2008, "one", :received, "ping", :sending, "pong"]
|
50
|
-
[Sun Jul 20 03:52:25 -0700 2008, "two", :received, "pong"]
|
51
|
-
|
52
|
-
[Sun Jul 20 03:52:26 -0700 2008, :sending, "ping"]
|
53
|
-
[Sun Jul 20 03:52:26 -0700 2008, "one", :received, "ping", :sending, "pong"]
|
54
|
-
[Sun Jul 20 03:52:26 -0700 2008, "two", :received, "pong"]
|
data/examples/pop.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
$:.unshift(File.expand_path("../../lib", __FILE__))
|
4
|
-
require 'amqp'
|
5
|
-
require 'pp'
|
6
|
-
|
7
|
-
Signal.trap('INT') { AMQP.stop { EM.stop } }
|
8
|
-
Signal.trap('TERM') { AMQP.stop { EM.stop } }
|
9
|
-
|
10
|
-
AMQP.start do
|
11
|
-
queue = AMQP::Channel.queue('awesome')
|
12
|
-
|
13
|
-
queue.publish('Totally rad 1')
|
14
|
-
queue.publish('Totally rad 2')
|
15
|
-
EM.add_timer(5) { queue.publish('Totally rad 3') }
|
16
|
-
|
17
|
-
queue.pop { |msg|
|
18
|
-
unless msg
|
19
|
-
# queue was empty
|
20
|
-
p [Time.now, :queue_empty!]
|
21
|
-
|
22
|
-
# try again in 1 second
|
23
|
-
EM.add_timer(1) { queue.pop }
|
24
|
-
else
|
25
|
-
# process this message
|
26
|
-
p [Time.now, msg]
|
27
|
-
|
28
|
-
# get the next message in the queue
|
29
|
-
queue.pop
|
30
|
-
end
|
31
|
-
}
|
32
|
-
end
|
33
|
-
|
34
|
-
__END__
|
35
|
-
|
36
|
-
[Wed Oct 15 15:24:30 -0700 2008, "Totally rad 1"]
|
37
|
-
[Wed Oct 15 15:24:30 -0700 2008, "Totally rad 2"]
|
38
|
-
[Wed Oct 15 15:24:30 -0700 2008, :queue_empty!]
|
39
|
-
[Wed Oct 15 15:24:31 -0700 2008, :queue_empty!]
|
40
|
-
[Wed Oct 15 15:24:32 -0700 2008, :queue_empty!]
|
41
|
-
[Wed Oct 15 15:24:33 -0700 2008, :queue_empty!]
|
42
|
-
[Wed Oct 15 15:24:34 -0700 2008, :queue_empty!]
|
43
|
-
[Wed Oct 15 15:24:35 -0700 2008, "Totally rad 3"]
|
44
|
-
[Wed Oct 15 15:24:35 -0700 2008, :queue_empty!]
|
45
|
-
[Wed Oct 15 15:24:36 -0700 2008, :queue_empty!]
|
data/examples/primes-simple.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
MAX = 1000
|
4
|
-
|
5
|
-
class Fixnum
|
6
|
-
def prime?
|
7
|
-
('1' * self) !~ /^1?$|^(11+?)\1+$/
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
class PrimeChecker
|
12
|
-
def is_prime? number
|
13
|
-
number.prime?
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
prime_checker = PrimeChecker.new
|
18
|
-
|
19
|
-
(10_000...(10_000+MAX)).each do |n|
|
20
|
-
prime_checker.is_prime? n
|
21
|
-
end
|
data/examples/primes.rb
DELETED
@@ -1,101 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
$:.unshift(File.expand_path("../../lib", __FILE__))
|
4
|
-
require 'amqp'
|
5
|
-
|
6
|
-
# check MAX numbers for prime-ness
|
7
|
-
MAX = 1000
|
8
|
-
|
9
|
-
# logging
|
10
|
-
def log(*args)
|
11
|
-
p args
|
12
|
-
end
|
13
|
-
|
14
|
-
# spawn workers
|
15
|
-
workers = ARGV[0] ? (Integer(ARGV[0]) rescue 1) : 1
|
16
|
-
AMQP.fork(workers) do
|
17
|
-
|
18
|
-
log AMQP::Channel.id, :started
|
19
|
-
|
20
|
-
class Fixnum
|
21
|
-
def prime?
|
22
|
-
('1' * self) !~ /^1?$|^(11+?)\1+$/
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
class PrimeChecker
|
27
|
-
def is_prime? number
|
28
|
-
log "prime checker #{AMQP::Channel.id}", :prime?, number
|
29
|
-
number.prime?
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
AMQP::Channel.rpc('prime checker', PrimeChecker.new)
|
34
|
-
|
35
|
-
end
|
36
|
-
|
37
|
-
# use workers to check which numbers are prime
|
38
|
-
AMQP.start(:host => 'localhost') do
|
39
|
-
|
40
|
-
prime_checker = AMQP::Channel.rpc('prime checker')
|
41
|
-
|
42
|
-
(10_000...(10_000+MAX)).each do |num|
|
43
|
-
log :checking, num
|
44
|
-
|
45
|
-
prime_checker.is_prime?(num) { |is_prime|
|
46
|
-
log :prime?, num, is_prime
|
47
|
-
(@primes||=[]) << num if is_prime
|
48
|
-
|
49
|
-
if (@responses = (@responses || 0) + 1) == MAX
|
50
|
-
log :primes=, @primes
|
51
|
-
EM.stop_event_loop
|
52
|
-
end
|
53
|
-
}
|
54
|
-
|
55
|
-
end
|
56
|
-
|
57
|
-
end
|
58
|
-
|
59
|
-
__END__
|
60
|
-
|
61
|
-
$ uname -a
|
62
|
-
Linux gc 2.6.24-ARCH #1 SMP PREEMPT Sun Mar 30 10:50:22 CEST 2008 x86_64 Intel(R) Xeon(R) CPU X3220 @ 2.40GHz GenuineIntel GNU/Linux
|
63
|
-
|
64
|
-
$ cat /proc/cpuinfo | grep processor | wc -l
|
65
|
-
4
|
66
|
-
|
67
|
-
$ time ruby primes-simple.rb
|
68
|
-
|
69
|
-
real 0m16.055s
|
70
|
-
user 0m16.052s
|
71
|
-
sys 0m0.000s
|
72
|
-
|
73
|
-
$ time ruby primes.rb 1 >/dev/null
|
74
|
-
|
75
|
-
real 0m18.278s
|
76
|
-
user 0m0.993s
|
77
|
-
sys 0m0.027s
|
78
|
-
|
79
|
-
$ time ruby primes.rb 2 >/dev/null
|
80
|
-
|
81
|
-
real 0m17.316s
|
82
|
-
user 0m0.967s
|
83
|
-
sys 0m0.053s
|
84
|
-
|
85
|
-
$ time ruby primes.rb 4 >/dev/null
|
86
|
-
|
87
|
-
real 0m8.229s
|
88
|
-
user 0m1.010s
|
89
|
-
sys 0m0.030s
|
90
|
-
|
91
|
-
$ time ruby primes.rb 8 >/dev/null
|
92
|
-
|
93
|
-
real 0m5.893s
|
94
|
-
user 0m1.023s
|
95
|
-
sys 0m0.050s
|
96
|
-
|
97
|
-
$ time ruby primes.rb 16 >/dev/null
|
98
|
-
|
99
|
-
real 0m5.601s
|
100
|
-
user 0m0.990s
|
101
|
-
sys 0m0.043s
|
data/examples/simple.rb
DELETED
@@ -1,81 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
$:.unshift(File.expand_path("../../lib", __FILE__))
|
4
|
-
require 'amqp'
|
5
|
-
|
6
|
-
module SimpleClient
|
7
|
-
def process_frame(frame)
|
8
|
-
case frame
|
9
|
-
when Frame::Body
|
10
|
-
EM.stop_event_loop
|
11
|
-
|
12
|
-
when Frame::Method
|
13
|
-
case method = frame.payload
|
14
|
-
when Protocol::Connection::Start
|
15
|
-
send Protocol::Connection::StartOk.new({:platform => 'Ruby/EventMachine',
|
16
|
-
:product => 'AMQP',
|
17
|
-
:information => 'http://github.com/ruby-amqp/amqp',
|
18
|
-
:version => '0.1.0'},
|
19
|
-
'AMQPLAIN',
|
20
|
-
{:LOGIN => 'guest',
|
21
|
-
:PASSWORD => 'guest'},
|
22
|
-
'en_US')
|
23
|
-
|
24
|
-
when Protocol::Connection::Tune
|
25
|
-
send Protocol::Connection::TuneOk.new(:channel_max => 0,
|
26
|
-
:frame_max => 131072,
|
27
|
-
:heartbeat => 0)
|
28
|
-
|
29
|
-
send Protocol::Connection::Open.new(:virtual_host => '/',
|
30
|
-
:capabilities => '',
|
31
|
-
:insist => false)
|
32
|
-
|
33
|
-
when Protocol::Connection::OpenOk
|
34
|
-
send Protocol::Channel::Open.new, :channel => 1
|
35
|
-
|
36
|
-
when Protocol::Channel::OpenOk
|
37
|
-
send Protocol::Access::Request.new(:realm => '/data',
|
38
|
-
:read => true,
|
39
|
-
:write => true,
|
40
|
-
:active => true), :channel => 1
|
41
|
-
|
42
|
-
when Protocol::Access::RequestOk
|
43
|
-
@ticket = method.ticket
|
44
|
-
send Protocol::Queue::Declare.new(:ticket => @ticket,
|
45
|
-
:queue => '',
|
46
|
-
:exclusive => false,
|
47
|
-
:auto_delete => true), :channel => 1
|
48
|
-
|
49
|
-
when Protocol::Queue::DeclareOk
|
50
|
-
@queue = method.queue
|
51
|
-
send Protocol::Queue::Bind.new(:ticket => @ticket,
|
52
|
-
:queue => @queue,
|
53
|
-
:exchange => '',
|
54
|
-
:routing_key => 'test_route'), :channel => 1
|
55
|
-
|
56
|
-
when Protocol::Queue::BindOk
|
57
|
-
send Protocol::Basic::Consume.new(:ticket => @ticket,
|
58
|
-
:queue => @queue,
|
59
|
-
:no_local => false,
|
60
|
-
:no_ack => true), :channel => 1
|
61
|
-
|
62
|
-
when Protocol::Basic::ConsumeOk
|
63
|
-
data = "this is a test!"
|
64
|
-
|
65
|
-
send Protocol::Basic::Publish.new(:ticket => @ticket,
|
66
|
-
:exchange => '',
|
67
|
-
:routing_key => 'test_route'), :channel => 1
|
68
|
-
send Protocol::Header.new(Protocol::Basic, data.length, :content_type => 'application/octet-stream',
|
69
|
-
:delivery_mode => 1,
|
70
|
-
:priority => 0), :channel => 1
|
71
|
-
send Frame::Body.new(data), :channel => 1
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
EM.run {
|
78
|
-
AMQP.logging = true
|
79
|
-
AMQP.client = SimpleClient
|
80
|
-
AMQP.start
|
81
|
-
}
|
data/examples/stocks.rb
DELETED
@@ -1,67 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
$:.unshift(File.expand_path("../../lib", __FILE__))
|
4
|
-
require 'amqp'
|
5
|
-
|
6
|
-
AMQP.start(:host => 'localhost') do |connection|
|
7
|
-
|
8
|
-
# Send Connection.Close on Ctrl+C
|
9
|
-
trap(:INT) do
|
10
|
-
unless connection.closing?
|
11
|
-
connection.close { exit! }
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def log(*args)
|
16
|
-
p [ Time.now, *args ]
|
17
|
-
end
|
18
|
-
|
19
|
-
def publish_stock_prices
|
20
|
-
mq = AMQP::Channel.new
|
21
|
-
EM.add_periodic_timer(1) {
|
22
|
-
puts
|
23
|
-
|
24
|
-
{ :appl => 170+rand(1000)/100.0,
|
25
|
-
:msft => 22+rand(500)/100.0
|
26
|
-
}.each do |stock, price|
|
27
|
-
stock = "usd.#{stock}"
|
28
|
-
|
29
|
-
log :publishing, stock, price
|
30
|
-
mq.topic('stocks').publish(price, :key => stock)
|
31
|
-
end
|
32
|
-
}
|
33
|
-
end
|
34
|
-
|
35
|
-
def watch_appl_stock
|
36
|
-
mq = AMQP::Channel.new
|
37
|
-
mq.queue('apple stock').bind(mq.topic('stocks'), :key => 'usd.appl').subscribe { |price|
|
38
|
-
log 'apple stock', price
|
39
|
-
}
|
40
|
-
end
|
41
|
-
|
42
|
-
def watch_us_stocks
|
43
|
-
mq = AMQP::Channel.new
|
44
|
-
mq.queue('us stocks').bind(mq.topic('stocks'), :key => 'usd.*').subscribe { |info, price|
|
45
|
-
log 'us stock', info.routing_key, price
|
46
|
-
}
|
47
|
-
end
|
48
|
-
|
49
|
-
publish_stock_prices
|
50
|
-
watch_appl_stock
|
51
|
-
watch_us_stocks
|
52
|
-
|
53
|
-
end
|
54
|
-
|
55
|
-
__END__
|
56
|
-
|
57
|
-
[Fri Aug 15 01:39:00 -0700 2008, :publishing, "usd.appl", 173.45]
|
58
|
-
[Fri Aug 15 01:39:00 -0700 2008, :publishing, "usd.msft", 26.98]
|
59
|
-
[Fri Aug 15 01:39:00 -0700 2008, "apple stock", "173.45"]
|
60
|
-
[Fri Aug 15 01:39:00 -0700 2008, "us stock", "usd.appl", "173.45"]
|
61
|
-
[Fri Aug 15 01:39:00 -0700 2008, "us stock", "usd.msft", "26.98"]
|
62
|
-
|
63
|
-
[Fri Aug 15 01:39:01 -0700 2008, :publishing, "usd.appl", 179.72]
|
64
|
-
[Fri Aug 15 01:39:01 -0700 2008, :publishing, "usd.msft", 26.56]
|
65
|
-
[Fri Aug 15 01:39:01 -0700 2008, "apple stock", "179.72"]
|
66
|
-
[Fri Aug 15 01:39:01 -0700 2008, "us stock", "usd.appl", "179.72"]
|
67
|
-
[Fri Aug 15 01:39:01 -0700 2008, "us stock", "usd.msft", "26.56"]
|
data/gemfiles/eventmachine-pre
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
source :rubygems
|
4
|
-
|
5
|
-
# Use local clones if possible.
|
6
|
-
# If you want to use your local copy, just symlink it to vendor.
|
7
|
-
def custom_gem(name, options = Hash.new)
|
8
|
-
local_path = File.expand_path("../vendor/#{name}", __FILE__)
|
9
|
-
if File.exist?(local_path)
|
10
|
-
gem name, options.merge(:path => local_path).delete_if { |key, _| [:git, :branch].include?(key) }
|
11
|
-
else
|
12
|
-
gem name, options
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
|
17
|
-
gem "eventmachine", "~> 1.0.0.beta3"
|
18
|
-
|
19
|
-
group(:test) do
|
20
|
-
gem "rspec", ">=2.0.0"
|
21
|
-
gem "rake"
|
22
|
-
# gem "amqp-spec", :git => "git://github.com/ruby-amqp/amqp-spec.git", :branch => "master"
|
23
|
-
custom_gem "evented-spec", :git => "git://github.com/ruby-amqp/evented-spec.git", :branch => "master"
|
24
|
-
end
|
data/lib/amqp/buffer.rb
DELETED
@@ -1,272 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
if [].map.respond_to? :with_index
|
4
|
-
class Array #:nodoc:
|
5
|
-
def enum_with_index
|
6
|
-
each.with_index
|
7
|
-
end
|
8
|
-
end
|
9
|
-
else
|
10
|
-
require 'enumerator'
|
11
|
-
end
|
12
|
-
|
13
|
-
module AMQP
|
14
|
-
class Buffer #:nodoc: all
|
15
|
-
class Overflow < StandardError; end
|
16
|
-
class InvalidType < StandardError; end
|
17
|
-
|
18
|
-
def initialize(data = '')
|
19
|
-
@data = data
|
20
|
-
@pos = 0
|
21
|
-
end
|
22
|
-
|
23
|
-
attr_reader :pos
|
24
|
-
|
25
|
-
def data
|
26
|
-
@data.clone
|
27
|
-
end
|
28
|
-
alias :contents :data
|
29
|
-
alias :to_s :data
|
30
|
-
|
31
|
-
def << data
|
32
|
-
@data << data.to_s
|
33
|
-
self
|
34
|
-
end
|
35
|
-
|
36
|
-
def length
|
37
|
-
@data.bytesize
|
38
|
-
end
|
39
|
-
|
40
|
-
def empty?
|
41
|
-
pos == length
|
42
|
-
end
|
43
|
-
|
44
|
-
def rewind
|
45
|
-
@pos = 0
|
46
|
-
end
|
47
|
-
|
48
|
-
def read_properties(*types)
|
49
|
-
types.shift if types.first == :properties
|
50
|
-
|
51
|
-
i = 0
|
52
|
-
values = []
|
53
|
-
|
54
|
-
while props = read(:short)
|
55
|
-
(0..14).each do |n|
|
56
|
-
# no more property types
|
57
|
-
break unless types[i]
|
58
|
-
|
59
|
-
# if flag is set
|
60
|
-
if props & (1 << (15-n)) != 0
|
61
|
-
if types[i] == :bit
|
62
|
-
# bit values exist in flags only
|
63
|
-
values << true
|
64
|
-
else
|
65
|
-
# save type name for later reading
|
66
|
-
values << types[i]
|
67
|
-
end
|
68
|
-
else
|
69
|
-
# property not set or is false bit
|
70
|
-
values << (types[i] == :bit ? false : nil)
|
71
|
-
end
|
72
|
-
|
73
|
-
i += 1
|
74
|
-
end
|
75
|
-
|
76
|
-
# bit(0) == 0 means no more property flags
|
77
|
-
break unless props & 1 == 1
|
78
|
-
end
|
79
|
-
|
80
|
-
values.map do |value|
|
81
|
-
value.is_a?(Symbol) ? read(value) : value
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def read(*types)
|
86
|
-
if types.first == :properties
|
87
|
-
return read_properties(*types)
|
88
|
-
end
|
89
|
-
|
90
|
-
values = types.map do |type|
|
91
|
-
case type
|
92
|
-
when :octet
|
93
|
-
_read(1, 'C')
|
94
|
-
when :short
|
95
|
-
_read(2, 'n')
|
96
|
-
when :long
|
97
|
-
_read(4, 'N')
|
98
|
-
when :longlong
|
99
|
-
upper, lower = _read(8, 'NN')
|
100
|
-
upper << 32 | lower
|
101
|
-
when :shortstr
|
102
|
-
_read read(:octet)
|
103
|
-
when :longstr
|
104
|
-
_read read(:long)
|
105
|
-
when :timestamp
|
106
|
-
Time.at read(:longlong)
|
107
|
-
when :table
|
108
|
-
t = Hash.new
|
109
|
-
|
110
|
-
table = Buffer.new(read(:longstr))
|
111
|
-
until table.empty?
|
112
|
-
key, type = table.read(:shortstr, :octet)
|
113
|
-
key = key.intern
|
114
|
-
t[key] ||= case type
|
115
|
-
when 83 # 'S'
|
116
|
-
table.read(:longstr)
|
117
|
-
when 73 # 'I'
|
118
|
-
table.read(:long)
|
119
|
-
when 68 # 'D'
|
120
|
-
exp = table.read(:octet)
|
121
|
-
num = table.read(:long)
|
122
|
-
num / 10.0**exp
|
123
|
-
when 84 # 'T'
|
124
|
-
table.read(:timestamp)
|
125
|
-
when 70 # 'F'
|
126
|
-
table.read(:table)
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
t
|
131
|
-
when :bit
|
132
|
-
if (@bits ||= []).empty?
|
133
|
-
val = read(:octet)
|
134
|
-
@bits = (0..7).map { |i| (val & 1 << i) != 0 }
|
135
|
-
end
|
136
|
-
|
137
|
-
@bits.shift
|
138
|
-
else
|
139
|
-
raise InvalidType, "Cannot read data of type #{type}"
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
types.size == 1 ? values.first : values
|
144
|
-
end
|
145
|
-
|
146
|
-
def write(type, data)
|
147
|
-
case type
|
148
|
-
when :octet
|
149
|
-
_write(data, 'C')
|
150
|
-
when :short
|
151
|
-
_write(data, 'n')
|
152
|
-
when :long
|
153
|
-
_write(data, 'N')
|
154
|
-
when :longlong
|
155
|
-
lower = data & 0xffffffff
|
156
|
-
upper = (data & ~0xffffffff) >> 32
|
157
|
-
_write([upper, lower], 'NN')
|
158
|
-
when :shortstr
|
159
|
-
data = (data || '').to_s
|
160
|
-
_write([data.bytesize, data], 'Ca*')
|
161
|
-
when :longstr
|
162
|
-
if data.is_a? Hash
|
163
|
-
write(:table, data)
|
164
|
-
else
|
165
|
-
data = (data || '').to_s
|
166
|
-
_write([data.bytesize, data], 'Na*')
|
167
|
-
end
|
168
|
-
when :timestamp
|
169
|
-
write(:longlong, data.to_i)
|
170
|
-
when :table
|
171
|
-
data ||= {}
|
172
|
-
write :longstr, (data.inject(Buffer.new) do |table, (key, value)|
|
173
|
-
table.write(:shortstr, key.to_s)
|
174
|
-
|
175
|
-
case value
|
176
|
-
when String
|
177
|
-
table.write(:octet, 83) # 'S'
|
178
|
-
table.write(:longstr, value.to_s)
|
179
|
-
when Fixnum
|
180
|
-
table.write(:octet, 73) # 'I'
|
181
|
-
table.write(:long, value)
|
182
|
-
when Float
|
183
|
-
table.write(:octet, 68) # 'D'
|
184
|
-
# XXX there's gotta be a better way to do this..
|
185
|
-
exp = value.to_s.split('.').last.bytesize
|
186
|
-
num = value * 10**exp
|
187
|
-
table.write(:octet, exp)
|
188
|
-
table.write(:long, num)
|
189
|
-
when Time
|
190
|
-
table.write(:octet, 84) # 'T'
|
191
|
-
table.write(:timestamp, value)
|
192
|
-
when Hash
|
193
|
-
table.write(:octet, 70) # 'F'
|
194
|
-
table.write(:table, value)
|
195
|
-
end
|
196
|
-
|
197
|
-
table
|
198
|
-
end)
|
199
|
-
when :bit
|
200
|
-
[*data].to_enum(:each_slice, 8).each { |bits|
|
201
|
-
write(:octet, bits.enum_with_index.inject(0) { |byte, (bit, i)|
|
202
|
-
byte |= 1 << i if bit
|
203
|
-
byte
|
204
|
-
})
|
205
|
-
}
|
206
|
-
when :properties
|
207
|
-
values = []
|
208
|
-
data.enum_with_index.inject(0) do |short, ((type, value), i)|
|
209
|
-
n = i % 15
|
210
|
-
last = i+1 == data.size
|
211
|
-
|
212
|
-
if (n == 0 and i != 0) or last
|
213
|
-
if data.size > i+1
|
214
|
-
short |= 1 << 0
|
215
|
-
elsif last and value
|
216
|
-
values << [type, value]
|
217
|
-
short |= 1 << (15-n)
|
218
|
-
end
|
219
|
-
|
220
|
-
write(:short, short)
|
221
|
-
short = 0
|
222
|
-
end
|
223
|
-
|
224
|
-
if value and !last
|
225
|
-
values << [type, value]
|
226
|
-
short |= 1 << (15-n)
|
227
|
-
end
|
228
|
-
|
229
|
-
short
|
230
|
-
end
|
231
|
-
|
232
|
-
values.each do |type, value|
|
233
|
-
write(type, value) unless type == :bit
|
234
|
-
end
|
235
|
-
else
|
236
|
-
raise InvalidType, "Cannot write data of type #{type}"
|
237
|
-
end
|
238
|
-
|
239
|
-
self
|
240
|
-
end
|
241
|
-
|
242
|
-
def extract
|
243
|
-
begin
|
244
|
-
cur_data, cur_pos = @data.clone, @pos
|
245
|
-
yield self
|
246
|
-
rescue Overflow
|
247
|
-
@data, @pos = cur_data, cur_pos
|
248
|
-
nil
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
|
-
def _read(size, pack = nil)
|
253
|
-
if @pos + size > length
|
254
|
-
raise Overflow
|
255
|
-
else
|
256
|
-
data = @data[@pos, size]
|
257
|
-
@data[@pos, size] = ''
|
258
|
-
if pack
|
259
|
-
data = data.unpack(pack)
|
260
|
-
data = data.pop if data.size == 1
|
261
|
-
end
|
262
|
-
data
|
263
|
-
end
|
264
|
-
end
|
265
|
-
|
266
|
-
def _write(data, pack = nil)
|
267
|
-
data = [*data].pack(pack) if pack
|
268
|
-
@data[@pos, 0] = data
|
269
|
-
@pos += data.bytesize
|
270
|
-
end
|
271
|
-
end
|
272
|
-
end
|