superbolt 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +266 -0
- data/Rakefile +1 -0
- data/lib/superbolt/adapter/amqp.rb +18 -0
- data/lib/superbolt/adapter/base.rb +28 -0
- data/lib/superbolt/adapter/bunny.rb +16 -0
- data/lib/superbolt/app.rb +73 -0
- data/lib/superbolt/config.rb +30 -0
- data/lib/superbolt/connection/app.rb +21 -0
- data/lib/superbolt/connection/base.rb +40 -0
- data/lib/superbolt/connection/queue.rb +25 -0
- data/lib/superbolt/facade.rb +26 -0
- data/lib/superbolt/incoming_message.rb +26 -0
- data/lib/superbolt/messenger.rb +66 -0
- data/lib/superbolt/processor.rb +33 -0
- data/lib/superbolt/queue.rb +93 -0
- data/lib/superbolt/version.rb +3 -0
- data/lib/superbolt.rb +22 -0
- data/spec/app_spec.rb +98 -0
- data/spec/config_spec.rb +78 -0
- data/spec/connection_spec.rb +21 -0
- data/spec/messenger_spec.rb +77 -0
- data/spec/queue_spec.rb +120 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/superbolt_spec.rb +55 -0
- data/spec/support/queue_helpers.rb +7 -0
- data/superbolt.gemspec +28 -0
- metadata +166 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
module Superbolt
|
2
|
+
class Processor
|
3
|
+
attr_reader :message, :logger, :block
|
4
|
+
attr_accessor :start_time, :exception
|
5
|
+
|
6
|
+
def initialize(message, logger, &block)
|
7
|
+
@message = message
|
8
|
+
@logger = logger
|
9
|
+
@block = block
|
10
|
+
end
|
11
|
+
|
12
|
+
def perform
|
13
|
+
start!
|
14
|
+
block.call(message.parse, logger)
|
15
|
+
finish!
|
16
|
+
true
|
17
|
+
rescue Exception => e
|
18
|
+
self.exception = e
|
19
|
+
logger.error("#{e.message}\n#{e.backtrace}")
|
20
|
+
false
|
21
|
+
end
|
22
|
+
|
23
|
+
def start!
|
24
|
+
self.start_time = Time.now
|
25
|
+
logger.info "[#{start_time}] Processing message: #{message.parse}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def finish!
|
29
|
+
end_time = Time.now
|
30
|
+
logger.info "[#{end_time}] Finished message: #{message.parse}\n in #{start_time - end_time} seconds"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module Superbolt
|
2
|
+
class Queue
|
3
|
+
attr_reader :name, :config
|
4
|
+
|
5
|
+
def initialize(name, config=nil)
|
6
|
+
@name = name
|
7
|
+
@config = config || Superbolt.config
|
8
|
+
end
|
9
|
+
|
10
|
+
def connection
|
11
|
+
@connection ||= Connection::Queue.new(name, config)
|
12
|
+
end
|
13
|
+
|
14
|
+
delegate :close, :closing, :exclusive?, :durable?, :auto_delete?,
|
15
|
+
:writer, :channel, :q,
|
16
|
+
to: :connection
|
17
|
+
|
18
|
+
def push(message)
|
19
|
+
closing do
|
20
|
+
writer.publish(message.to_json, routing_key: name)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def size
|
25
|
+
closing do
|
26
|
+
q.message_count
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def clear
|
31
|
+
closing do
|
32
|
+
q.purge
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# TODO: roll up some of these subscribe methods
|
37
|
+
|
38
|
+
def read
|
39
|
+
messages = []
|
40
|
+
closing do
|
41
|
+
q.subscribe(:ack => true) do |delivery_info, metadata, payload|
|
42
|
+
message = IncomingMessage.new(delivery_info, payload, channel)
|
43
|
+
messages << message
|
44
|
+
end
|
45
|
+
end
|
46
|
+
messages
|
47
|
+
end
|
48
|
+
|
49
|
+
def all
|
50
|
+
read.map(&:parse)
|
51
|
+
end
|
52
|
+
|
53
|
+
def peek
|
54
|
+
all.first
|
55
|
+
end
|
56
|
+
|
57
|
+
def pop
|
58
|
+
messages = []
|
59
|
+
closing do
|
60
|
+
popped = false
|
61
|
+
q.subscribe(:ack => false) do |delivery_info, metadata, message|
|
62
|
+
next if popped
|
63
|
+
messages << IncomingMessage.new(delivery_info, message, channel)
|
64
|
+
popped = true
|
65
|
+
end
|
66
|
+
end
|
67
|
+
message = messages.first
|
68
|
+
message && message.parse
|
69
|
+
end
|
70
|
+
|
71
|
+
delegate :slice, :[],
|
72
|
+
to: :all
|
73
|
+
|
74
|
+
def delete
|
75
|
+
messages = []
|
76
|
+
closing do
|
77
|
+
q.subscribe(:ack => true) do |delivery_info, metadata, payload|
|
78
|
+
message = IncomingMessage.new(delivery_info, payload, channel)
|
79
|
+
relevant = yield(message.parse)
|
80
|
+
if relevant
|
81
|
+
messages << message.parse
|
82
|
+
message.ack
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# channel is closed by block before message ack can complete
|
87
|
+
# therefore we must sleep :(
|
88
|
+
sleep 0.02
|
89
|
+
end
|
90
|
+
messages
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
data/lib/superbolt.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
require 'bunny'
|
4
|
+
require 'amqp'
|
5
|
+
require 'active_support/core_ext/module/delegation'
|
6
|
+
|
7
|
+
require "superbolt/version"
|
8
|
+
require "superbolt/config"
|
9
|
+
require "superbolt/adapter/base"
|
10
|
+
require "superbolt/adapter/bunny"
|
11
|
+
require "superbolt/adapter/amqp"
|
12
|
+
require "superbolt/connection/base"
|
13
|
+
require "superbolt/connection/queue"
|
14
|
+
require "superbolt/connection/app"
|
15
|
+
require "superbolt/queue"
|
16
|
+
require "superbolt/incoming_message"
|
17
|
+
require "superbolt/app"
|
18
|
+
require "superbolt/processor"
|
19
|
+
require "superbolt/facade"
|
20
|
+
require "superbolt/messenger"
|
21
|
+
|
22
|
+
$stdout.sync = true
|
data/spec/app_spec.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Superbolt::App do
|
4
|
+
let(:env) { 'test' }
|
5
|
+
let(:name) { 'superbolt' }
|
6
|
+
let(:logger) { Logger.new('/dev/null') }
|
7
|
+
let(:app) {
|
8
|
+
Superbolt::App.new(name, {
|
9
|
+
env: env,
|
10
|
+
logger: logger
|
11
|
+
})
|
12
|
+
}
|
13
|
+
let(:queue) { Superbolt::Queue.new("#{name}_#{env}") }
|
14
|
+
let(:quit_queue) { Superbolt::Queue.new("#{name}_#{env}.quit") }
|
15
|
+
let(:error_queue) { Superbolt::Queue.new("#{name}_#{env}.error") }
|
16
|
+
let(:messages) { [] }
|
17
|
+
|
18
|
+
before do
|
19
|
+
queue.clear
|
20
|
+
quit_queue.clear
|
21
|
+
error_queue.clear
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#run' do
|
25
|
+
it "shuts down with any message to the quit queue" do
|
26
|
+
queue.push({please: 'stop'})
|
27
|
+
|
28
|
+
app.run do |arguments|
|
29
|
+
quit_queue.push({message: 'just because'})
|
30
|
+
end
|
31
|
+
|
32
|
+
queue.size.should == 0
|
33
|
+
quit_queue.size.should == 0
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'passes messages to the block for processing' do
|
37
|
+
queue.push({first: 1})
|
38
|
+
queue.push({last: 2})
|
39
|
+
|
40
|
+
app.run do |message, logger|
|
41
|
+
messages << message
|
42
|
+
quit_queue.push({message: 'quit'}) if message['last']
|
43
|
+
end
|
44
|
+
|
45
|
+
messages.size.should == 2
|
46
|
+
messages.should == [
|
47
|
+
{'first' => 1},
|
48
|
+
{'last' => 2}
|
49
|
+
]
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'removes messages from the queue on successful completion' do
|
53
|
+
queue.push({first: 1})
|
54
|
+
queue.push({last: 2})
|
55
|
+
|
56
|
+
app.run do |message, logger|
|
57
|
+
messages << message
|
58
|
+
quit_queue.push({message: 'quit'}) if message['last']
|
59
|
+
end
|
60
|
+
|
61
|
+
queue.size.should == 0
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
it "passes a logger to the block" do
|
66
|
+
mock_logger = double
|
67
|
+
app.logger = mock_logger
|
68
|
+
|
69
|
+
message_received = false
|
70
|
+
mock_logger.stub(:info) do |m|
|
71
|
+
if m == {'write' => 'out'}
|
72
|
+
message_received = true
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
queue.push({write: 'out'})
|
77
|
+
|
78
|
+
app.run do |message, logger|
|
79
|
+
logger.info(message)
|
80
|
+
quit_queue.push({message: 'stop!'})
|
81
|
+
end
|
82
|
+
|
83
|
+
message_received.should be_true
|
84
|
+
end
|
85
|
+
|
86
|
+
it "moves the message to an error queue if an exception is raised" do
|
87
|
+
queue.push({oh: 'noes'})
|
88
|
+
|
89
|
+
app.run do |message|
|
90
|
+
quit_queue.push({message: 'halt thyself'})
|
91
|
+
raise "something went wrong"
|
92
|
+
end
|
93
|
+
|
94
|
+
queue.size.should == 0
|
95
|
+
error_queue.size.should == 1
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Superbolt::Config do
|
4
|
+
let(:config) {
|
5
|
+
Superbolt::Config.new(options)
|
6
|
+
}
|
7
|
+
|
8
|
+
let(:options) {
|
9
|
+
{}
|
10
|
+
}
|
11
|
+
|
12
|
+
describe '#connection' do
|
13
|
+
context "environmental variables" do
|
14
|
+
context 'default behavior' do
|
15
|
+
let(:old_value) { ENV['RABBITMQ_URL'] }
|
16
|
+
let(:url) { 'http://cloudamqp-url.com' }
|
17
|
+
|
18
|
+
before do
|
19
|
+
old_value
|
20
|
+
ENV['RABBITMQ_URL'] = url
|
21
|
+
end
|
22
|
+
|
23
|
+
after do
|
24
|
+
ENV['RABBITMQ_URL'] = old_value
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns the RABBITMQ_URL" do
|
28
|
+
config.connection_params.should == url
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'additional configuration passed in' do
|
33
|
+
let(:old_value) { ENV['SOMEOTHERURL'] }
|
34
|
+
let(:url) { 'http://someother-url.com' }
|
35
|
+
let(:options) {
|
36
|
+
{connection_key: 'SOMEOTHERURL'}
|
37
|
+
}
|
38
|
+
|
39
|
+
before do
|
40
|
+
old_value
|
41
|
+
ENV['SOMEOTHERURL'] = url
|
42
|
+
end
|
43
|
+
|
44
|
+
after do
|
45
|
+
ENV['SOMEOTHERURL'] = old_value
|
46
|
+
end
|
47
|
+
|
48
|
+
it "returns the url specified in the env" do
|
49
|
+
config.connection_params.should == url
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'no environmental variables' do
|
55
|
+
context 'default' do
|
56
|
+
it "uses the default url" do
|
57
|
+
config.connection_params.should == {
|
58
|
+
:host => '127.0.0.1'
|
59
|
+
}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'connection params passed in' do
|
64
|
+
let(:options) {
|
65
|
+
{
|
66
|
+
connection_params: {
|
67
|
+
:host => 'hoo.com'
|
68
|
+
}
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
it "uses what it is given" do
|
73
|
+
config.connection_params.should == options[:connection_params]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Superbolt::Adapter::Bunny do
|
4
|
+
let(:connection) { Superbolt::Adapter::Bunny.new }
|
5
|
+
|
6
|
+
it "has an underlying open connection via Bunny" do
|
7
|
+
connection.socket.should be_a Bunny::Session
|
8
|
+
connection.socket.should be_open
|
9
|
+
connection.should be_open
|
10
|
+
end
|
11
|
+
|
12
|
+
it "has a channel" do
|
13
|
+
connection.channel.should be_a Bunny::Channel
|
14
|
+
end
|
15
|
+
|
16
|
+
it "delegates queue creation to the channel" do
|
17
|
+
queue = connection.queue('changelica')
|
18
|
+
queue.should be_a Bunny::Queue
|
19
|
+
connection.queues.keys.should include('changelica')
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Superbolt::Messenger do
|
4
|
+
let(:env) { 'test' }
|
5
|
+
let(:name) { 'my_friend_app' }
|
6
|
+
let(:queue) { Superbolt::Queue.new("#{name}_#{env}") }
|
7
|
+
|
8
|
+
before do
|
9
|
+
queue.clear
|
10
|
+
Superbolt.env = env
|
11
|
+
Superbolt.app_name = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:messenger) { Superbolt::Messenger.new }
|
15
|
+
|
16
|
+
describe 'queue generation' do
|
17
|
+
it "can be instantiated with a queue destination" do
|
18
|
+
m = Superbolt::Messenger.new(to: name)
|
19
|
+
m.name.should == name
|
20
|
+
m.queue.name.should == "#{name}_#{env}"
|
21
|
+
end
|
22
|
+
|
23
|
+
it "destination queue can be set via #from" do
|
24
|
+
messenger.to('activator')
|
25
|
+
messenger.queue.name.should == "activator_#{env}"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "raises an error if the name is nil" do
|
29
|
+
expect {
|
30
|
+
messenger.queue
|
31
|
+
}.to raise_error
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe 'underlying message' do
|
36
|
+
let(:message) { messenger.message }
|
37
|
+
|
38
|
+
it "starts its life with no interesting values" do
|
39
|
+
message[:origin].should == nil
|
40
|
+
message[:event].should == 'default'
|
41
|
+
message[:arguments].should == {}
|
42
|
+
end
|
43
|
+
|
44
|
+
it "calls to #from, set the origin on the message" do
|
45
|
+
messenger.from('linkticounter')
|
46
|
+
message[:origin].should == 'linkticounter'
|
47
|
+
end
|
48
|
+
|
49
|
+
it "passes event data to the message" do
|
50
|
+
messenger.re('zap')
|
51
|
+
message[:event].should == 'zap'
|
52
|
+
end
|
53
|
+
|
54
|
+
it "passes data to the message" do
|
55
|
+
messenger.data({foo: 'bar'})
|
56
|
+
message[:arguments].should == {foo: 'bar'}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe 'send!' do
|
61
|
+
before do
|
62
|
+
messenger
|
63
|
+
.to(name)
|
64
|
+
.from('me')
|
65
|
+
.re('love')
|
66
|
+
end
|
67
|
+
|
68
|
+
it "returns a hash that gets sent to the right queue" do
|
69
|
+
messenger.send!('none')
|
70
|
+
queue.pop.should == {
|
71
|
+
'origin' => 'me',
|
72
|
+
'event' => 'love',
|
73
|
+
'arguments' => 'none'
|
74
|
+
}
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/spec/queue_spec.rb
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Superbolt::Queue' do
|
4
|
+
let(:name) { 'superbolt_test' }
|
5
|
+
let(:connection) { Superbolt::Connection.new }
|
6
|
+
let(:queue) { Superbolt::Queue.new(name) }
|
7
|
+
let(:messages) { [] }
|
8
|
+
|
9
|
+
before do
|
10
|
+
queue.clear
|
11
|
+
end
|
12
|
+
|
13
|
+
it "has the right name" do
|
14
|
+
queue.name.should == name
|
15
|
+
end
|
16
|
+
|
17
|
+
it "is setup with the right defaults" do
|
18
|
+
queue.exclusive?.should be_false
|
19
|
+
queue.durable?.should be_true
|
20
|
+
queue.auto_delete?.should be_false
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'queue/array operations' do
|
24
|
+
let(:message) { {hello: 'insomniacs'} }
|
25
|
+
let(:decoded) { {'hello' => 'insomniacs'} }
|
26
|
+
|
27
|
+
describe '#push' do
|
28
|
+
let(:bunny_queue) {connection.queue(name, Superbolt::Queue.default_options)}
|
29
|
+
|
30
|
+
it "writes to the queue" do
|
31
|
+
queue.push(message)
|
32
|
+
queue.size.should == 1
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#peek' do
|
37
|
+
it "returns the message but leaves it in the queue" do
|
38
|
+
queue.push(message)
|
39
|
+
queue.peek.should == decoded
|
40
|
+
queue.size.should == 1
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#pop' do
|
45
|
+
it "returns the message and deletes it from the queue" do
|
46
|
+
queue.push(message)
|
47
|
+
queue.pop.should == decoded
|
48
|
+
queue.size.should == 0
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#all' do
|
53
|
+
before do
|
54
|
+
queue.push(message)
|
55
|
+
queue.push(message)
|
56
|
+
queue.push(message)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "returns all the messages on the queue" do
|
60
|
+
messages = queue.all
|
61
|
+
messages.size.should == 3
|
62
|
+
messages.uniq.should == [decoded]
|
63
|
+
end
|
64
|
+
|
65
|
+
it "does not consume the messages" do
|
66
|
+
queue.size.should == 3
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe '#slice(offset, n)' do
|
71
|
+
before do
|
72
|
+
(0..9).to_a.each do |i|
|
73
|
+
queue.push(message.merge(i: i))
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
it "returns a set of messages determined by the offset and the number requested" do
|
78
|
+
messages = queue.slice(1,3)
|
79
|
+
messages.size.should == 3
|
80
|
+
messages.map{|json| json['i']}.should == [1,2,3]
|
81
|
+
end
|
82
|
+
|
83
|
+
it "does not consume messages" do
|
84
|
+
queue.slice(1,3)
|
85
|
+
queue.size.should == 10
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe '#[i]' do
|
90
|
+
before do
|
91
|
+
(0..9).to_a.each do |i|
|
92
|
+
queue.push(message.merge(i: i))
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
it "return the message at the i-th position without removing it from the queue" do
|
97
|
+
json = queue[3]
|
98
|
+
json['i'].should == 3
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe '#delete(&block)' do
|
103
|
+
before do
|
104
|
+
(0..9).to_a.each do |i|
|
105
|
+
queue.push(message.merge(i: i))
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
it "returns all messages where the block is true" do
|
110
|
+
messages = queue.delete{|json| json['i'] > 2 && json['i'] != 6 && json['i'] < 8 }
|
111
|
+
messages.map{|json| json['i']}.should == [3,4,5,7]
|
112
|
+
end
|
113
|
+
|
114
|
+
it "removes those messages from the queue" do
|
115
|
+
queue.delete{|json| json['i'] > 2 && json['i'] != 6 && json['i'] < 8 }
|
116
|
+
queue.size.should == 6
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Superbolt, 'the facade' do
|
4
|
+
describe '.config' do
|
5
|
+
after do
|
6
|
+
Superbolt.instance_eval do
|
7
|
+
@config = nil
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it "stores the default" do
|
12
|
+
Superbolt.config.should == Superbolt::Config.new
|
13
|
+
end
|
14
|
+
|
15
|
+
it "can be customized" do
|
16
|
+
Superbolt.config = {
|
17
|
+
connection_key: 'SOME_RABBITMQ_URL'
|
18
|
+
}
|
19
|
+
|
20
|
+
Superbolt.config.env_connection_key.should == 'SOME_RABBITMQ_URL'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '.queue' do
|
25
|
+
it "creates a queue with the default config" do
|
26
|
+
queue = double('queue')
|
27
|
+
Superbolt::Queue.should_receive(:new)
|
28
|
+
.with('queue_name', Superbolt.config)
|
29
|
+
.and_return(queue)
|
30
|
+
Superbolt.queue('queue_name').should == queue
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '.message' do
|
35
|
+
it "sends messages via the messenger system" do
|
36
|
+
queue = Superbolt.queue('activator_test')
|
37
|
+
queue.clear
|
38
|
+
Superbolt.env = 'test'
|
39
|
+
Superbolt.app_name = 'bossanova'
|
40
|
+
|
41
|
+
Superbolt.message
|
42
|
+
.to('activator')
|
43
|
+
.re('update')
|
44
|
+
.send!({class: 'Advocate'})
|
45
|
+
|
46
|
+
queue.pop.should == {
|
47
|
+
'origin' => 'bossanova',
|
48
|
+
'event' => 'update',
|
49
|
+
'arguments' => {
|
50
|
+
'class' => 'Advocate'
|
51
|
+
}
|
52
|
+
}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/superbolt.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'superbolt/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "superbolt"
|
8
|
+
spec.version = Superbolt::VERSION
|
9
|
+
spec.authors = ["socialchorus"]
|
10
|
+
spec.email = ["developers@socialchorus.com"]
|
11
|
+
spec.description = %q{Superbolt is comprised of a standalone app, and a queue-like queue for sending messages between services and applications.}
|
12
|
+
spec.summary = %q{Superbolt is a gem that makes SOA intra-app communication easy, via RabbitMQ}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "activesupport"
|
22
|
+
spec.add_dependency "amqp"
|
23
|
+
spec.add_dependency "bunny", "~> 0.9.0.rc1"
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
26
|
+
spec.add_development_dependency "rake"
|
27
|
+
spec.add_development_dependency "rspec"
|
28
|
+
end
|