qsagi 0.0.3 → 0.1.0
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.
- checksums.yaml +7 -0
- data/lib/qsagi.rb +2 -0
- data/lib/qsagi/confirmed_queue.rb +66 -0
- data/lib/qsagi/message.rb +4 -8
- data/lib/qsagi/queue.rb +36 -49
- data/lib/qsagi/standard_queue.rb +70 -0
- data/lib/qsagi/version.rb +1 -1
- data/qsagi.gemspec +1 -1
- data/spec/qsagi/confirmed_queue_spec.rb +33 -0
- data/spec/qsagi/message_spec.rb +5 -23
- data/spec/qsagi/queue_spec.rb +35 -1
- data/spec/spec_helper.rb +4 -5
- metadata +13 -15
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5abc20946ce817158e4ccbcd23c4297457dfa967
|
4
|
+
data.tar.gz: b454ffe9a3616b7796f6c4b83d6b7f003b8fe8da
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4c29980ce4a2bb9bfb1a069731f6568c3f09354d3da65499fee67cd08bfa487e7f8504eb7447103a0f46e3d04c958722e5d7e75f708fa9181b7b95a6fb6bbe28
|
7
|
+
data.tar.gz: 4d9dad24f276baec8bd09c2b2d5c9ba19cc25538b452e83f0c9a87fa80da66b56a65d2de19f43322324c0fd1ee7cd210f739661a5df51d822645d5454e8411f6
|
data/lib/qsagi.rb
CHANGED
@@ -0,0 +1,66 @@
|
|
1
|
+
module Qsagi
|
2
|
+
class ConfirmedQueue
|
3
|
+
attr_reader :nacked_messages
|
4
|
+
|
5
|
+
def initialize(queue)
|
6
|
+
@queue = queue
|
7
|
+
@nacked_messages = []
|
8
|
+
@unconfirmed_messages = {}
|
9
|
+
@wait_for_confirms = false
|
10
|
+
end
|
11
|
+
|
12
|
+
def connect
|
13
|
+
@queue.connect
|
14
|
+
_confirm_select
|
15
|
+
end
|
16
|
+
|
17
|
+
def disconnect
|
18
|
+
@queue.disconnect
|
19
|
+
end
|
20
|
+
|
21
|
+
def push(message)
|
22
|
+
@unconfirmed_messages[_channel.next_publish_seq_no] = message
|
23
|
+
@queue.push(message)
|
24
|
+
@wait_for_confirms = true
|
25
|
+
end
|
26
|
+
|
27
|
+
def pop(opts={})
|
28
|
+
@queue.pop(opts)
|
29
|
+
end
|
30
|
+
|
31
|
+
def wait_for_confirms
|
32
|
+
_channel.wait_for_confirms if _wait_for_confirms?
|
33
|
+
end
|
34
|
+
|
35
|
+
def _channel
|
36
|
+
@queue.channel
|
37
|
+
end
|
38
|
+
|
39
|
+
def _confirm_messages!(attributes)
|
40
|
+
if attributes[:is_nack]
|
41
|
+
if attributes[:multiple]
|
42
|
+
@nacked_messages += @unconfirmed_messages.select { |k,v| k <= attributes[:delivery_tag] }.values
|
43
|
+
@unconfirmed_messages.delete_if { |k,v| k <= attributes[:delivery_tag] }
|
44
|
+
else
|
45
|
+
@nacked_messages << @unconfirmed_messages.delete(attributes[:delivery_tag])
|
46
|
+
end
|
47
|
+
else
|
48
|
+
if attributes[:multiple]
|
49
|
+
@unconfirmed_messages.delete_if { |k,v| k <= attributes[:delivery_tag] }
|
50
|
+
else
|
51
|
+
@unconfirmed_messages.delete(attributes[:delivery_tag])
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def _confirm_select
|
57
|
+
_channel.confirm_select lambda { |delivery_tag, multiple, is_nack|
|
58
|
+
_confirm_messages!(:delivery_tag => delivery_tag, :multiple => multiple, :is_nack => is_nack)
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
def _wait_for_confirms?
|
63
|
+
@wait_for_confirms
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/qsagi/message.rb
CHANGED
@@ -2,21 +2,17 @@ module Qsagi
|
|
2
2
|
class Message
|
3
3
|
attr_reader :payload
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
@
|
5
|
+
def initialize(delivery_details, payload)
|
6
|
+
@delivery_details = delivery_details
|
7
7
|
@payload = payload
|
8
8
|
end
|
9
9
|
|
10
10
|
def delivery_tag
|
11
|
-
|
11
|
+
@delivery_details.delivery_tag
|
12
12
|
end
|
13
13
|
|
14
14
|
def exchange
|
15
|
-
|
16
|
-
end
|
17
|
-
|
18
|
-
def _delivery_details
|
19
|
-
@delivery_details ||= @message.fetch(:delivery_details, {})
|
15
|
+
@delivery_details.exchange
|
20
16
|
end
|
21
17
|
end
|
22
18
|
end
|
data/lib/qsagi/queue.rb
CHANGED
@@ -1,58 +1,13 @@
|
|
1
1
|
module Qsagi
|
2
2
|
module Queue
|
3
|
-
def ack(message)
|
4
|
-
@queue.ack(:delivery_tag => message.delivery_tag)
|
5
|
-
end
|
6
|
-
|
7
|
-
def clear
|
8
|
-
loop do
|
9
|
-
message = @queue.pop
|
10
|
-
break if message[:payload] == :queue_empty
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def connect
|
15
|
-
@client = Bunny.new(:host => self.class.host, :port => self.class.port, :heartbeat => self.class.heartbeat)
|
16
|
-
@client.start
|
17
|
-
@queue = @client.queue(self.class.queue_name, :durable => true, :arguments => {"x-ha-policy" => "all"})
|
18
|
-
@exchange = @client.exchange(self.class._exchange)
|
19
|
-
@queue.bind(@exchange, :key => self.class.queue_name) unless self.class._exchange.empty?
|
20
|
-
end
|
21
|
-
|
22
|
-
def disconnect
|
23
|
-
@client.send(:close_socket) unless @client.nil?
|
24
|
-
end
|
25
|
-
|
26
|
-
def length
|
27
|
-
@queue.status[:message_count]
|
28
|
-
end
|
29
|
-
|
30
|
-
def pop(options = {})
|
31
|
-
auto_ack = options.fetch(:auto_ack, true)
|
32
|
-
message = @queue.pop(:ack => !auto_ack)
|
33
|
-
|
34
|
-
unless message[:payload] == :queue_empty
|
35
|
-
self.class._message_class.new(message, self.class._serializer.deserialize(message[:payload]))
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def push(message)
|
40
|
-
serialized_message = self.class._serializer.serialize(message)
|
41
|
-
@exchange.publish(serialized_message, :key => @queue.name, :persistent => true, :mandatory => true)
|
42
|
-
end
|
43
|
-
|
44
|
-
def reconnect
|
45
|
-
disconnect
|
46
|
-
connect
|
47
|
-
end
|
48
|
-
|
49
3
|
def self.included(klass)
|
50
4
|
klass.extend ClassMethods
|
51
5
|
end
|
52
6
|
|
53
7
|
module ClassMethods
|
54
|
-
def connect(&block)
|
55
|
-
|
8
|
+
def connect(opts={}, &block)
|
9
|
+
options = default_options.merge(opts)
|
10
|
+
queue = _queue(options)
|
56
11
|
|
57
12
|
begin
|
58
13
|
queue.connect
|
@@ -63,8 +18,36 @@ module Qsagi
|
|
63
18
|
end
|
64
19
|
end
|
65
20
|
|
66
|
-
def
|
21
|
+
def _queue(options)
|
22
|
+
standard_queue = StandardQueue.new(options)
|
23
|
+
if options[:queue_type] == :confirmed
|
24
|
+
ConfirmedQueue.new(standard_queue)
|
25
|
+
else
|
26
|
+
standard_queue
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def default_options
|
31
|
+
{
|
32
|
+
:host => host,
|
33
|
+
:port => port,
|
34
|
+
:queue_type => :standard,
|
35
|
+
:heartbeat => heartbeat,
|
36
|
+
:message_class => _message_class,
|
37
|
+
:queue_name => queue_name,
|
38
|
+
:durable => true,
|
39
|
+
:queue_arguments => {"x-ha-policy" => "all"},
|
40
|
+
:persistent => true,
|
41
|
+
:mandatory => true,
|
42
|
+
:serializer => _serializer,
|
43
|
+
:exchange_options => _exchange_options,
|
44
|
+
:exchange => _exchange
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
def exchange(exchange, options = {})
|
67
49
|
@exchange = exchange
|
50
|
+
@exchange_options = {:type => :direct}.merge(options)
|
68
51
|
end
|
69
52
|
|
70
53
|
def message_class(message_class)
|
@@ -79,6 +62,10 @@ module Qsagi
|
|
79
62
|
@exchange || ""
|
80
63
|
end
|
81
64
|
|
65
|
+
def _exchange_options
|
66
|
+
@exchange_options || {}
|
67
|
+
end
|
68
|
+
|
82
69
|
def _message_class
|
83
70
|
@message_class || Qsagi::Message
|
84
71
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Qsagi
|
2
|
+
class StandardQueue
|
3
|
+
attr_reader :channel, :options
|
4
|
+
|
5
|
+
def initialize(options={})
|
6
|
+
@options = options
|
7
|
+
end
|
8
|
+
|
9
|
+
def ack(message)
|
10
|
+
@channel.ack(message.delivery_tag, false)
|
11
|
+
end
|
12
|
+
|
13
|
+
def reject(message, options={})
|
14
|
+
@channel.reject(message.delivery_tag, options.fetch(:requeue, true))
|
15
|
+
end
|
16
|
+
|
17
|
+
def clear
|
18
|
+
@queue.purge
|
19
|
+
end
|
20
|
+
|
21
|
+
def connect
|
22
|
+
@client = Bunny.new(
|
23
|
+
:host => options[:host],
|
24
|
+
:port => options[:port],
|
25
|
+
:heartbeat => options[:heartbeat],
|
26
|
+
:continuation_timeout => options[:continuation_timeout]
|
27
|
+
)
|
28
|
+
@client.start
|
29
|
+
@channel = @client.create_channel
|
30
|
+
@exchange = @channel.exchange(options[:exchange], options[:exchange_options])
|
31
|
+
@queue = @channel.queue(options[:queue_name], :durable => options[:durable], :arguments => options[:queue_arguments])
|
32
|
+
@queue.bind(@exchange, :routing_key => options[:queue_name]) unless options[:exchange].empty?
|
33
|
+
end
|
34
|
+
|
35
|
+
def disconnect
|
36
|
+
@client.close unless @client.nil?
|
37
|
+
end
|
38
|
+
|
39
|
+
def length
|
40
|
+
@queue.status[:message_count]
|
41
|
+
end
|
42
|
+
|
43
|
+
def pop(options = {})
|
44
|
+
auto_ack = options.fetch(:auto_ack, true)
|
45
|
+
delivery_info, properties, message = @queue.pop(:ack => !auto_ack)
|
46
|
+
|
47
|
+
unless message.nil?
|
48
|
+
_message_class.new(delivery_info, _serializer.deserialize(message))
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def push(message)
|
53
|
+
serialized_message = options[:serializer].serialize(message)
|
54
|
+
@exchange.publish(serialized_message, :routing_key => @queue.name, :persistent => options[:persistent], :mandatory => options[:mandatory])
|
55
|
+
end
|
56
|
+
|
57
|
+
def reconnect
|
58
|
+
disconnect
|
59
|
+
connect
|
60
|
+
end
|
61
|
+
|
62
|
+
def _message_class
|
63
|
+
options[:message_class]
|
64
|
+
end
|
65
|
+
|
66
|
+
def _serializer
|
67
|
+
options[:serializer]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/qsagi/version.rb
CHANGED
data/qsagi.gemspec
CHANGED
@@ -0,0 +1,33 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Qsagi::ConfirmedQueue do
|
4
|
+
describe "_confirm_messages!" do
|
5
|
+
it "adds a single nacked message to nacked_messages" do
|
6
|
+
queue = Qsagi::ConfirmedQueue.new(nil)
|
7
|
+
queue.instance_variable_set(:@unconfirmed_messages, {2 => "message"})
|
8
|
+
queue._confirm_messages!(:delivery_tag => 2, :multiple => false, :is_nack => true)
|
9
|
+
queue.nacked_messages.should == ["message"]
|
10
|
+
end
|
11
|
+
|
12
|
+
it "adds multiple nacked messages to nacked_messages" do
|
13
|
+
queue = Qsagi::ConfirmedQueue.new(nil)
|
14
|
+
queue.instance_variable_set(:@unconfirmed_messages, {2 => "message", 3 => "other_message"})
|
15
|
+
queue._confirm_messages!(:delivery_tag => 3, :multiple => true, :is_nack => true)
|
16
|
+
queue.nacked_messages.should == ["message", "other_message"]
|
17
|
+
end
|
18
|
+
|
19
|
+
it "removes a single acked message from unconfirmed_messages" do
|
20
|
+
queue = Qsagi::ConfirmedQueue.new(nil)
|
21
|
+
queue.instance_variable_set(:@unconfirmed_messages, {2 => "message", 3 => "other_message"})
|
22
|
+
queue._confirm_messages!(:delivery_tag => 2, :multiple => false, :is_nack => false)
|
23
|
+
queue.instance_variable_get(:@unconfirmed_messages).should == {3 => "other_message"}
|
24
|
+
end
|
25
|
+
|
26
|
+
it "removes multiple acked messages from unconfirmed_messages" do
|
27
|
+
queue = Qsagi::ConfirmedQueue.new(nil)
|
28
|
+
queue.instance_variable_set(:@unconfirmed_messages, {2 => "message", 3 => "other_message", 4 => "this_dude"})
|
29
|
+
queue._confirm_messages!(:delivery_tag => 3, :multiple => true, :is_nack => false)
|
30
|
+
queue.instance_variable_get(:@unconfirmed_messages).should == {4 => "this_dude"}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/spec/qsagi/message_spec.rb
CHANGED
@@ -3,39 +3,21 @@ require "spec_helper"
|
|
3
3
|
describe Qsagi::Message do
|
4
4
|
describe "delivery_tag" do
|
5
5
|
it "returns the delivery_tag" do
|
6
|
-
|
7
|
-
|
8
|
-
:payload => "raw_payload"
|
9
|
-
}
|
10
|
-
Qsagi::Message.new(data, :parsed_payload).delivery_tag.should == "tag"
|
11
|
-
end
|
12
|
-
|
13
|
-
it "gracefully handles no delivery details" do
|
14
|
-
Qsagi::Message.new({}, :parsed_payload).delivery_tag.should be_nil
|
6
|
+
delivery_details = OpenStruct.new(:delivery_tag => "tag")
|
7
|
+
Qsagi::Message.new(delivery_details, :parsed_payload).delivery_tag.should == "tag"
|
15
8
|
end
|
16
9
|
end
|
17
10
|
|
18
11
|
describe "exchange" do
|
19
12
|
it "returns the exchange" do
|
20
|
-
|
21
|
-
|
22
|
-
:payload => "raw_payload"
|
23
|
-
}
|
24
|
-
Qsagi::Message.new(data, :parsed_payload).exchange.should == "the_exchange"
|
25
|
-
end
|
26
|
-
|
27
|
-
it "gracefully handles no delivery details" do
|
28
|
-
Qsagi::Message.new({}, :parsed_payload).exchange.should be_nil
|
13
|
+
delivery_details = OpenStruct.new(:exchange => "the_exchange")
|
14
|
+
Qsagi::Message.new(delivery_details, :parsed_payload).exchange.should == "the_exchange"
|
29
15
|
end
|
30
16
|
end
|
31
17
|
|
32
18
|
describe "payload" do
|
33
19
|
it "returns the parsed payload" do
|
34
|
-
|
35
|
-
:delivery_details => {:delivery_tag => "tag"},
|
36
|
-
:payload => "raw_payload"
|
37
|
-
}
|
38
|
-
Qsagi::Message.new(data, :parsed_payload).payload.should == :parsed_payload
|
20
|
+
Qsagi::Message.new(:deliver_details, :parsed_payload).payload.should == :parsed_payload
|
39
21
|
end
|
40
22
|
end
|
41
23
|
end
|
data/spec/qsagi/queue_spec.rb
CHANGED
@@ -12,7 +12,7 @@ describe Qsagi::Queue do
|
|
12
12
|
describe "self.exchange" do
|
13
13
|
it "configures the exchange" do
|
14
14
|
queue_on_exchange1 = Class.new(ExampleQueue) do
|
15
|
-
exchange "exchange1"
|
15
|
+
exchange "exchange1", :type => :direct
|
16
16
|
end
|
17
17
|
queue_on_exchange2 = Class.new(ExampleQueue) do
|
18
18
|
exchange "exchange2"
|
@@ -54,6 +54,30 @@ describe Qsagi::Queue do
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
+
describe "reject" do
|
58
|
+
it "rejects the message and places it back on the queue" do
|
59
|
+
ExampleQueue.connect do |queue|
|
60
|
+
queue.push("message")
|
61
|
+
message = queue.pop(:auto_ack => false)
|
62
|
+
queue.reject(message, :requeue => true)
|
63
|
+
end
|
64
|
+
ExampleQueue.connect do |queue|
|
65
|
+
queue.length.should == 1
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it "rejects and discards the message" do
|
70
|
+
ExampleQueue.connect do |queue|
|
71
|
+
queue.push("message")
|
72
|
+
message = queue.pop(:auto_ack => false)
|
73
|
+
queue.reject(message, :requeue => false)
|
74
|
+
end
|
75
|
+
ExampleQueue.connect do |queue|
|
76
|
+
queue.length.should == 0
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
57
81
|
describe "pop" do
|
58
82
|
it "automatically acks if :auto_ack is not passed in" do
|
59
83
|
ExampleQueue.connect do |queue|
|
@@ -84,4 +108,14 @@ describe Qsagi::Queue do
|
|
84
108
|
end
|
85
109
|
end
|
86
110
|
end
|
111
|
+
|
112
|
+
describe "queue_type confirmed" do
|
113
|
+
it "should use a ConfirmedQueue" do
|
114
|
+
ExampleQueue.connect(:queue_type => :confirmed) do |queue|
|
115
|
+
queue.push("message")
|
116
|
+
queue.wait_for_confirms
|
117
|
+
queue.nacked_messages.size.should == 0
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
87
121
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "qsagi"
|
2
|
+
require "ostruct"
|
2
3
|
|
3
4
|
class ExampleQueue
|
4
5
|
include Qsagi::Queue
|
@@ -22,10 +23,8 @@ end
|
|
22
23
|
|
23
24
|
RSpec.configure do |c|
|
24
25
|
c.before(:each) do
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
queue.delete rescue nil
|
29
|
-
client.send(:close_socket)
|
26
|
+
ExampleQueue.connect do |queue|
|
27
|
+
queue.clear
|
28
|
+
end
|
30
29
|
end
|
31
30
|
end
|
metadata
CHANGED
@@ -1,36 +1,32 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qsagi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
5
|
-
prerelease:
|
4
|
+
version: 0.1.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Braintree
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-05-15 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: bunny
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
17
|
- - ~>
|
20
18
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
19
|
+
version: 1.1.0
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
24
|
- - ~>
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
26
|
+
version: 1.1.0
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: json
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
31
|
- - ~>
|
36
32
|
- !ruby/object:Gem::Version
|
@@ -38,7 +34,6 @@ dependencies:
|
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
38
|
- - ~>
|
44
39
|
- !ruby/object:Gem::Version
|
@@ -56,41 +51,44 @@ files:
|
|
56
51
|
- README.md
|
57
52
|
- Rakefile
|
58
53
|
- lib/qsagi.rb
|
54
|
+
- lib/qsagi/confirmed_queue.rb
|
59
55
|
- lib/qsagi/default_serializer.rb
|
60
56
|
- lib/qsagi/json_serializer.rb
|
61
57
|
- lib/qsagi/message.rb
|
62
58
|
- lib/qsagi/queue.rb
|
59
|
+
- lib/qsagi/standard_queue.rb
|
63
60
|
- lib/qsagi/version.rb
|
64
61
|
- qsagi.gemspec
|
62
|
+
- spec/qsagi/confirmed_queue_spec.rb
|
65
63
|
- spec/qsagi/json_serializer_spec.rb
|
66
64
|
- spec/qsagi/message_spec.rb
|
67
65
|
- spec/qsagi/queue_spec.rb
|
68
66
|
- spec/spec_helper.rb
|
69
67
|
homepage: https://github.com/braintree/qsagi
|
70
68
|
licenses: []
|
69
|
+
metadata: {}
|
71
70
|
post_install_message:
|
72
71
|
rdoc_options: []
|
73
72
|
require_paths:
|
74
73
|
- lib
|
75
74
|
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
-
none: false
|
77
75
|
requirements:
|
78
|
-
- -
|
76
|
+
- - '>='
|
79
77
|
- !ruby/object:Gem::Version
|
80
78
|
version: '0'
|
81
79
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
-
none: false
|
83
80
|
requirements:
|
84
|
-
- -
|
81
|
+
- - '>='
|
85
82
|
- !ruby/object:Gem::Version
|
86
83
|
version: '0'
|
87
84
|
requirements: []
|
88
85
|
rubyforge_project:
|
89
|
-
rubygems_version:
|
86
|
+
rubygems_version: 2.2.2
|
90
87
|
signing_key:
|
91
|
-
specification_version:
|
88
|
+
specification_version: 4
|
92
89
|
summary: A friendly way to talk to RabbitMQ
|
93
90
|
test_files:
|
91
|
+
- spec/qsagi/confirmed_queue_spec.rb
|
94
92
|
- spec/qsagi/json_serializer_spec.rb
|
95
93
|
- spec/qsagi/message_spec.rb
|
96
94
|
- spec/qsagi/queue_spec.rb
|