micro_q 0.9.2 → 0.9.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +1 -1
- data/README.md +48 -0
- data/bin/microq +11 -0
- data/lib/micro_q/cli.rb +60 -0
- data/lib/micro_q/config.rb +15 -0
- data/lib/micro_q/fetchers/sqs.rb +37 -0
- data/lib/micro_q/inspect.rb +17 -0
- data/lib/micro_q/manager/default.rb +9 -1
- data/lib/micro_q/queue/sqs.rb +85 -0
- data/lib/micro_q/queue.rb +1 -0
- data/lib/micro_q/sqs_client.rb +47 -0
- data/lib/micro_q/version.rb +1 -1
- data/lib/micro_q.rb +7 -1
- data/micro_q.gemspec +3 -0
- data/spec/helpers/queues_examples.rb +1 -1
- data/spec/lib/config_spec.rb +47 -0
- data/spec/lib/fetchers/sqs_spec.rb +81 -0
- data/spec/lib/manager/default_spec.rb +69 -0
- data/spec/lib/queue/redis_spec.rb +0 -5
- data/spec/lib/queue/sqs_spec.rb +206 -0
- data/spec/lib/sqs_client_spec.rb +166 -0
- data/spec/spec_helper.rb +19 -5
- metadata +58 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f8736323665ab0facb37dfc92fd2463077cfe0f0
|
4
|
+
data.tar.gz: e7f7022cd9c3c74efbb68f68d85f49270436ca8c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aeeea9df0091afbb6593457b7664b36e21edd7800f1e5dc3cd6d71b6a92ecba6c9e7540413b75d18bf89020b6f65efa033097de0f1372e5ac68ff6bd604d4161
|
7
|
+
data.tar.gz: e2ebf0f5f4c4e116c432979276e0d0c436fad69cbc6f6b0475d7e240a0d3b46c824e4ae85c79cea797e8d9f2f06ac3976451dc88e3311152cd43ce29e5634735
|
data/.rspec
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
--color
|
2
|
-
--format
|
2
|
+
--format Fuubar
|
data/README.md
CHANGED
@@ -49,6 +49,9 @@ MyWorker.update_async(:user_id => user.id)
|
|
49
49
|
|
50
50
|
Safely using an ActiveRecord instance via the [Custom Loader](https://github.com/bnorton/micro_q/wiki/Loaders) API
|
51
51
|
```ruby
|
52
|
+
# config/initializers/micro_q
|
53
|
+
require 'micro_q/methods/active_record'
|
54
|
+
|
52
55
|
# app/models/user.rb
|
53
56
|
class User < Activerecord::Base
|
54
57
|
def update_social_data
|
@@ -63,6 +66,51 @@ def update
|
|
63
66
|
end
|
64
67
|
```
|
65
68
|
|
69
|
+
##Queues
|
70
|
+
By default the queue is an in-memory queue meaning that messages are shared per-process
|
71
|
+
and any unprocessed messages are saved to a file when shutdown occurs.
|
72
|
+
|
73
|
+
The **Redis queue** requires some configuration in your gemfile to keep the runtime dependencies to a minimum
|
74
|
+
```ruby
|
75
|
+
# Gemfile
|
76
|
+
gem 'redis'
|
77
|
+
gem 'micro_q'
|
78
|
+
|
79
|
+
# config/initializers/micro_q.rb
|
80
|
+
require 'redis'
|
81
|
+
require 'micro_q'
|
82
|
+
|
83
|
+
# when MicroQ starts simply use the redis queue
|
84
|
+
MicroQ.configure do |config|
|
85
|
+
config.queue = MicroQ::Queue::Redis
|
86
|
+
end
|
87
|
+
```
|
88
|
+
|
89
|
+
The **Amazon SQS (coming soon) queue** require some extra configuration in your gemfile.
|
90
|
+
```ruby
|
91
|
+
# Gemfile
|
92
|
+
gem 'aws-sdk'
|
93
|
+
gem 'micro_q'
|
94
|
+
|
95
|
+
# config/initializers/micro_q.rb
|
96
|
+
require 'aws-sdk'
|
97
|
+
require 'micro_q'
|
98
|
+
|
99
|
+
# when MicroQ starts simply use the sqs queue
|
100
|
+
# this will take care of all other switchover for the system
|
101
|
+
MicroQ.configure do |config|
|
102
|
+
config.queue = MicroQ::Queue::Sqs
|
103
|
+
config.aws = { :key => 'YOUR KEY', :secret => 'YOUR SECRET' }
|
104
|
+
end
|
105
|
+
|
106
|
+
**Note that when using the SQS Queue only the MicroQ's started via command-line will actually process messages**
|
107
|
+
|
108
|
+
# Then just use the queues in your workers
|
109
|
+
class SomeWorker
|
110
|
+
worker :queue => :critical
|
111
|
+
end
|
112
|
+
```
|
113
|
+
|
66
114
|
## Contributing
|
67
115
|
|
68
116
|
1. Fork it
|
data/bin/microq
ADDED
data/lib/micro_q/cli.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'slop'
|
2
|
+
require 'micro_q'
|
3
|
+
|
4
|
+
module MicroQ
|
5
|
+
class CLI
|
6
|
+
def self.run
|
7
|
+
@cli ||= new
|
8
|
+
@cli.parse
|
9
|
+
@cli.verify!
|
10
|
+
@cli.setup
|
11
|
+
end
|
12
|
+
|
13
|
+
def parse
|
14
|
+
opts = Slop.parse do
|
15
|
+
banner 'Usage: microq [options]'
|
16
|
+
|
17
|
+
on 'r=', 'The path to the rails application'
|
18
|
+
on 'require=', 'The path to the rails application'
|
19
|
+
on 'w=', 'The number of worker threads'
|
20
|
+
on 'workers=', 'The number of worker threads'
|
21
|
+
end
|
22
|
+
|
23
|
+
@workers = opts[:workers] || opts[:w]
|
24
|
+
@require = opts[:require] || opts[:r]
|
25
|
+
end
|
26
|
+
|
27
|
+
def verify!
|
28
|
+
raise "Need a valid path to a rails application, you gave us #{@require}\n" unless /environment\.rb/ === @require || File.exist?("#{@require}/config/application.rb")
|
29
|
+
end
|
30
|
+
|
31
|
+
def setup
|
32
|
+
puts 'Requiring rails...'
|
33
|
+
require 'rails'
|
34
|
+
|
35
|
+
puts 'Requiring rails application...'
|
36
|
+
if File.directory?(@require)
|
37
|
+
require File.expand_path("#{@require}/config/environment.rb")
|
38
|
+
else
|
39
|
+
require @require
|
40
|
+
end
|
41
|
+
|
42
|
+
aws_keys = MicroQ.config.aws.try(:keys) || []
|
43
|
+
raise 'SQS mode requires an aws :key and :secret see https://github.com/bnorton/micro_q/wiki/Named-Queues' unless aws_keys.include?(:key) && aws_keys.include?(:secret)
|
44
|
+
|
45
|
+
MicroQ.configure do |config|
|
46
|
+
config.queue = MicroQ::Queue::Sqs # set workers after since this must set workers=0 internally
|
47
|
+
config.workers = @workers.to_i if @workers
|
48
|
+
config['worker_mode?'] = true
|
49
|
+
end
|
50
|
+
|
51
|
+
puts "Running micro_q in SQS mode with #{MicroQ.config.workers} workers... Hit ctl+c to stop...\n"
|
52
|
+
MicroQ.start
|
53
|
+
|
54
|
+
sleep
|
55
|
+
rescue Interrupt
|
56
|
+
puts 'Exiting via interrupt'
|
57
|
+
exit(1)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/micro_q/config.rb
CHANGED
@@ -13,11 +13,13 @@ module MicroQ
|
|
13
13
|
'workers' => 5,
|
14
14
|
'timeout' => 120,
|
15
15
|
'interval' => 5,
|
16
|
+
'env' => defined?(Rails) ? Rails.env : 'development',
|
16
17
|
'middleware' => Middleware::Chain.new,
|
17
18
|
'manager' => Manager::Default,
|
18
19
|
'worker' => Worker::Standard,
|
19
20
|
'queue' => Queue::Default,
|
20
21
|
'statistics' => Statistics::Default,
|
22
|
+
'aws' => {},
|
21
23
|
'redis_pool' => { :size => 15, :timeout => 1 },
|
22
24
|
'redis' => { :host => 'localhost', :port => 6379 }
|
23
25
|
}
|
@@ -31,6 +33,19 @@ module MicroQ
|
|
31
33
|
@data[key.to_s]
|
32
34
|
end
|
33
35
|
|
36
|
+
def queue=(q)
|
37
|
+
if q == Queue::Sqs
|
38
|
+
require 'aws-sdk'
|
39
|
+
|
40
|
+
@data['sqs?'] = true
|
41
|
+
@data['workers'] = 0
|
42
|
+
end
|
43
|
+
|
44
|
+
@data['queue'] = q
|
45
|
+
rescue LoadError
|
46
|
+
raise "Looks you need `gem 'aws-sdk'` in your Gemfile to use the SQS queue."
|
47
|
+
end
|
48
|
+
|
34
49
|
def method_missing(method, *args)
|
35
50
|
case method
|
36
51
|
when /(.+)=$/ then @data[$1] = args.first
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module MicroQ
|
2
|
+
module Fetcher
|
3
|
+
class Sqs
|
4
|
+
include Celluloid
|
5
|
+
attr_reader :name
|
6
|
+
|
7
|
+
def initialize(name, manager)
|
8
|
+
@name = name.to_s
|
9
|
+
@manager = manager
|
10
|
+
end
|
11
|
+
|
12
|
+
def start
|
13
|
+
defer do
|
14
|
+
client.messages.tap do |messages|
|
15
|
+
@manager.receive_messages!(messages) if messages.any?
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
after(2) { start }
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_message(message, time=nil)
|
23
|
+
message['run_at'] = time.to_f if time
|
24
|
+
|
25
|
+
defer do
|
26
|
+
client.messages_create(message)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def client
|
33
|
+
@client ||= MicroQ::SqsClient.new(name)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module MicroQ
|
2
|
+
module Inspect
|
3
|
+
def self.included(base)
|
4
|
+
base.send(:include, InstanceMethods)
|
5
|
+
end
|
6
|
+
|
7
|
+
module InstanceMethods
|
8
|
+
def inspect
|
9
|
+
"#<#{self.class.name}: #{self.object_id}>"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
['Worker::Standard', 'Queue::Default', 'Queue::Redis', 'Queue::Sqs', 'Manager::Default', 'Fetcher::Sqs'].each do |postfix|
|
16
|
+
MicroQ::Util.constantize("MicroQ::#{postfix}").send(:include, MicroQ::Inspect)
|
17
|
+
end
|
@@ -23,6 +23,8 @@ module MicroQ
|
|
23
23
|
attr_reader :queue, :workers
|
24
24
|
|
25
25
|
def start
|
26
|
+
return if queue_only?
|
27
|
+
|
26
28
|
count = workers.size
|
27
29
|
|
28
30
|
if (messages = queue.dequeue(count)).any?
|
@@ -53,6 +55,7 @@ module MicroQ
|
|
53
55
|
end
|
54
56
|
|
55
57
|
@busy ||= []
|
58
|
+
@workers ||= []
|
56
59
|
|
57
60
|
build_missing_workers
|
58
61
|
end
|
@@ -61,9 +64,10 @@ module MicroQ
|
|
61
64
|
|
62
65
|
# Don't shrink the pool if the config changes
|
63
66
|
def build_missing_workers
|
64
|
-
|
67
|
+
return if queue_only?
|
65
68
|
|
66
69
|
workers.select!(&:alive?)
|
70
|
+
@busy.select!(&:alive?)
|
67
71
|
|
68
72
|
missing_worker_count.times do
|
69
73
|
workers << MicroQ.config.worker.new_link(current_actor)
|
@@ -78,6 +82,10 @@ module MicroQ
|
|
78
82
|
(@workers + @busy).each {|w| w.terminate if w.alive? }
|
79
83
|
end
|
80
84
|
|
85
|
+
def queue_only?
|
86
|
+
@queue_only ||= MicroQ.config.sqs? && !MicroQ.config.worker_mode?
|
87
|
+
end
|
88
|
+
|
81
89
|
def self.shutdown?
|
82
90
|
!!@shutdown
|
83
91
|
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module MicroQ
|
2
|
+
module Queue
|
3
|
+
class Sqs
|
4
|
+
include Celluloid
|
5
|
+
|
6
|
+
exit_handler :build_missing_fetchers
|
7
|
+
|
8
|
+
attr_accessor :messages
|
9
|
+
attr_reader :fetchers, :entries, :later
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@lock = Mutex.new
|
13
|
+
|
14
|
+
@messages, @entries, @later = [], [], []
|
15
|
+
@fetcher_map = {}
|
16
|
+
|
17
|
+
build_missing_fetchers
|
18
|
+
end
|
19
|
+
|
20
|
+
def push(item)
|
21
|
+
async.sync_push(item)
|
22
|
+
end
|
23
|
+
|
24
|
+
def sync_push(item, options={})
|
25
|
+
item, options = MicroQ::Util.stringify(item, options)
|
26
|
+
item['class'] = item['class'].to_s
|
27
|
+
|
28
|
+
MicroQ.middleware.client.call(item, options) do
|
29
|
+
args, queue_name = [item], verify_queue(item['queue'].to_s)
|
30
|
+
|
31
|
+
if (time = options['when'])
|
32
|
+
args << time.to_f
|
33
|
+
end
|
34
|
+
|
35
|
+
@fetcher_map[queue_name].add_message(*args)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def receive_messages(*items)
|
40
|
+
@lock.synchronize do
|
41
|
+
(@messages += items).flatten!
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def dequeue(limit=30)
|
46
|
+
return [] unless limit > 0 && messages.any?
|
47
|
+
|
48
|
+
@lock.synchronize do
|
49
|
+
limit.times.collect do
|
50
|
+
messages.pop
|
51
|
+
end.compact
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def verify_queue(name)
|
56
|
+
QUEUES_KEYS.include?(name) ? name : 'default'
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.shutdown!
|
60
|
+
@shutdown = true
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def self.shutdown?
|
66
|
+
@shutdown
|
67
|
+
end
|
68
|
+
|
69
|
+
def build_missing_fetchers(*)
|
70
|
+
return if self.class.shutdown?
|
71
|
+
|
72
|
+
@fetchers = QUEUES_KEYS.map do |name|
|
73
|
+
((existing = @fetcher_map[name]) && existing.alive? && existing) ||
|
74
|
+
MicroQ::Fetcher::Sqs.new_link(name, current_actor).tap do |fetcher|
|
75
|
+
@fetcher_map[name] = fetcher
|
76
|
+
fetcher.start!
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
QUEUES = { 'low' => 1, 'default' => 3, 'critical' => 5 }
|
82
|
+
QUEUES_KEYS = QUEUES.keys
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/lib/micro_q/queue.rb
CHANGED
@@ -0,0 +1,47 @@
|
|
1
|
+
module MicroQ
|
2
|
+
class SqsClient
|
3
|
+
attr_reader :url
|
4
|
+
|
5
|
+
def initialize(name)
|
6
|
+
@name = "#{MicroQ.config.env}_#{name}"
|
7
|
+
@url = client.create_queue(:queue_name => @name)[:queue_url]
|
8
|
+
end
|
9
|
+
|
10
|
+
def messages
|
11
|
+
response = client.receive_message(
|
12
|
+
:queue_url => url,
|
13
|
+
:wait_time_seconds => 10,
|
14
|
+
:max_number_of_messages => 10,
|
15
|
+
:visibility_timeout => 5 * 60
|
16
|
+
)
|
17
|
+
|
18
|
+
((response && response[:messages]) || []).collect do |message|
|
19
|
+
JSON.parse(message[:body]).merge(
|
20
|
+
'sqs_id' => message[:message_id],
|
21
|
+
'sqs_handle' => message[:receipt_handle],
|
22
|
+
'sqs_queue' => url
|
23
|
+
)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def messages_create(message)
|
28
|
+
attrs = {
|
29
|
+
:queue_url => url,
|
30
|
+
:message_body => message.to_json
|
31
|
+
}
|
32
|
+
|
33
|
+
attrs[:delay_seconds] = (message['run_at'].to_i - Time.now.to_i) if message.key?('run_at')
|
34
|
+
|
35
|
+
client.send_message(attrs)[:message_id]
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def client
|
41
|
+
@client ||= AWS::SQS::Client.new(
|
42
|
+
:access_key_id => MicroQ.config.aws[:key],
|
43
|
+
:secret_access_key => MicroQ.config.aws[:secret]
|
44
|
+
)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/micro_q/version.rb
CHANGED
data/lib/micro_q.rb
CHANGED
@@ -6,6 +6,8 @@ require 'micro_q/util'
|
|
6
6
|
require 'micro_q/config'
|
7
7
|
require 'micro_q/manager'
|
8
8
|
|
9
|
+
Celluloid.logger = nil
|
10
|
+
|
9
11
|
module MicroQ
|
10
12
|
def self.config
|
11
13
|
@config ||= Config.new
|
@@ -51,17 +53,20 @@ require 'micro_q/proxies'
|
|
51
53
|
require 'micro_q/dsl'
|
52
54
|
require 'micro_q/worker'
|
53
55
|
require 'micro_q/queue'
|
56
|
+
require 'micro_q/sqs_client'
|
54
57
|
|
58
|
+
require 'micro_q/fetchers/sqs'
|
55
59
|
require 'micro_q/redis'
|
60
|
+
require 'micro_q/inspect'
|
56
61
|
|
57
62
|
require 'micro_q/wrappers/action_mailer'
|
58
63
|
|
64
|
+
|
59
65
|
# add Class and Instance methods first then
|
60
66
|
# override with additional extensions
|
61
67
|
|
62
68
|
require 'micro_q/methods/class'
|
63
69
|
require 'micro_q/methods/instance'
|
64
|
-
require 'micro_q/methods/active_record'
|
65
70
|
require 'micro_q/methods/action_mailer'
|
66
71
|
|
67
72
|
require 'micro_q/statistics/base'
|
@@ -71,4 +76,5 @@ require 'micro_q/statistics/redis'
|
|
71
76
|
# There is a better way coming soon 2/18/13
|
72
77
|
at_exit do
|
73
78
|
MicroQ::Manager::Default.shutdown!
|
79
|
+
MicroQ::Queue::Sqs.shutdown!
|
74
80
|
end
|
data/micro_q.gemspec
CHANGED
@@ -19,7 +19,9 @@ Gem::Specification.new do |gem|
|
|
19
19
|
|
20
20
|
gem.add_dependency "celluloid", '~> 0.12.0'
|
21
21
|
gem.add_dependency "connection_pool"
|
22
|
+
gem.add_dependency "slop"
|
22
23
|
gem.add_development_dependency "rake"
|
24
|
+
gem.add_development_dependency "fuubar"
|
23
25
|
gem.add_development_dependency "rspec"
|
24
26
|
gem.add_development_dependency "timecop"
|
25
27
|
gem.add_development_dependency "psych"
|
@@ -27,4 +29,5 @@ Gem::Specification.new do |gem|
|
|
27
29
|
gem.add_development_dependency "actionmailer", "> 3.2.0"
|
28
30
|
gem.add_development_dependency "sqlite3-ruby"
|
29
31
|
gem.add_development_dependency "mock_redis"
|
32
|
+
gem.add_development_dependency "aws-sdk"
|
30
33
|
end
|
data/spec/lib/config_spec.rb
CHANGED
@@ -36,6 +36,14 @@ describe MicroQ::Config do
|
|
36
36
|
subject.timeout.should == 120
|
37
37
|
end
|
38
38
|
|
39
|
+
it 'should have the default env' do
|
40
|
+
subject.env.should == 'development'
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should not be in sqs mode' do
|
44
|
+
subject.should_not be_sqs
|
45
|
+
end
|
46
|
+
|
39
47
|
it 'should have middleware chain' do
|
40
48
|
subject.middleware.class.should == MicroQ::Middleware::Chain
|
41
49
|
end
|
@@ -68,4 +76,43 @@ describe MicroQ::Config do
|
|
68
76
|
subject.statistics.should == MicroQ::Statistics::Default
|
69
77
|
end
|
70
78
|
end
|
79
|
+
|
80
|
+
describe 'when rails is defined' do
|
81
|
+
before do
|
82
|
+
module Rails end
|
83
|
+
def Rails.env; 'the-env' end
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should have the rails env' do
|
87
|
+
subject.env.should == 'the-env'
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe '#queue=' do
|
92
|
+
before do
|
93
|
+
subject.queue = 'blah-blah'
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should have the given queue' do
|
97
|
+
subject.queue.should == 'blah-blah'
|
98
|
+
end
|
99
|
+
|
100
|
+
describe 'when setting the SQS queue' do
|
101
|
+
before do
|
102
|
+
subject.queue = MicroQ::Queue::Sqs
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should have the given queue' do
|
106
|
+
subject.queue.should == MicroQ::Queue::Sqs
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'should enable sqs mode' do
|
110
|
+
subject.sqs?.should == true
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'should have zero workers' do
|
114
|
+
subject.workers.should == 0
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
71
118
|
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MicroQ::Fetcher::Sqs do
|
4
|
+
let(:queue) { mock(MicroQ::Queue::Sqs, :receive_messages! => nil) }
|
5
|
+
|
6
|
+
subject { MicroQ::Fetcher::Sqs.new(:low, queue) }
|
7
|
+
|
8
|
+
before do
|
9
|
+
@client = mock(MicroQ::SqsClient, :messages => [])
|
10
|
+
MicroQ::SqsClient.stub(:new => @client)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '.new' do
|
14
|
+
it 'should have the queue name' do
|
15
|
+
subject.name.should == 'low'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#start' do
|
20
|
+
it 'should create an sqs client' do
|
21
|
+
MicroQ::SqsClient.should_receive(:new).with('low').and_return(@client)
|
22
|
+
|
23
|
+
subject.start
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'when called again' do
|
27
|
+
it 'should create an sqs client' do
|
28
|
+
MicroQ::SqsClient.should_receive(:new).and_return(@client)
|
29
|
+
subject.start
|
30
|
+
|
31
|
+
MicroQ::SqsClient.rspec_verify
|
32
|
+
MicroQ::SqsClient.rspec_reset
|
33
|
+
|
34
|
+
MicroQ::SqsClient.should_not_receive(:new)
|
35
|
+
|
36
|
+
subject.start
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should request messages from the queue' do
|
41
|
+
@client.should_receive(:messages)
|
42
|
+
|
43
|
+
subject.start
|
44
|
+
end
|
45
|
+
|
46
|
+
describe 'when there are messages in the queue' do
|
47
|
+
let(:messages) { 2.times.map {|i| mock("message_#{i}") }}
|
48
|
+
|
49
|
+
before do
|
50
|
+
@client.stub(:messages).and_return(messages)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should hand of the messages to the manager' do
|
54
|
+
queue.should_receive(:receive_messages!).with(messages)
|
55
|
+
|
56
|
+
subject.start
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#add_message' do
|
62
|
+
let(:message) { {'class' => 'FooBar'} }
|
63
|
+
let(:add_message) { subject.add_message(message) }
|
64
|
+
|
65
|
+
it 'should create the message' do
|
66
|
+
@client.should_receive(:messages_create).with(message)
|
67
|
+
|
68
|
+
add_message
|
69
|
+
end
|
70
|
+
|
71
|
+
describe 'when the message has an associated time' do
|
72
|
+
let(:add_message) { subject.add_message(message, Time.now.to_i) }
|
73
|
+
|
74
|
+
it 'should send the time' do
|
75
|
+
@client.should_receive(:messages_create).with(message.merge('run_at' => Time.now.to_i))
|
76
|
+
|
77
|
+
add_message
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -82,6 +82,38 @@ describe MicroQ::Manager::Default do
|
|
82
82
|
|
83
83
|
subject.start
|
84
84
|
end
|
85
|
+
|
86
|
+
describe 'when the manager is in SQS mode' do
|
87
|
+
before do
|
88
|
+
MicroQ.config['sqs?'] = true
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should not perform the items' do
|
92
|
+
@queue.should_not_receive(:dequeue)
|
93
|
+
[@worker1, @worker2].each {|w| w.should_not_receive(:perform!) }
|
94
|
+
|
95
|
+
subject.start
|
96
|
+
end
|
97
|
+
|
98
|
+
describe 'when in worker mode' do
|
99
|
+
before do
|
100
|
+
MicroQ.config['worker_mode?'] = true
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'should dequeue the number of free workers' do
|
104
|
+
@queue.should_receive(:dequeue).with(2)
|
105
|
+
|
106
|
+
subject.start
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'should perform the items' do
|
110
|
+
@worker1.should_receive(:perform!).with(@other_item)
|
111
|
+
@worker2.should_receive(:perform!).with(@item)
|
112
|
+
|
113
|
+
subject.start
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
85
117
|
end
|
86
118
|
end
|
87
119
|
|
@@ -144,6 +176,43 @@ describe MicroQ::Manager::Default do
|
|
144
176
|
|
145
177
|
subject.workers.should == [@worker1, @new_worker2]
|
146
178
|
end
|
179
|
+
|
180
|
+
describe 'when a busy worker has died' do
|
181
|
+
before do
|
182
|
+
subject.wrapped_object.instance_variable_set(:@busy, [@worker2])
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'should restart the dead worker' do
|
186
|
+
MicroQ::Worker::Standard.should_receive(:new_link).and_return(@new_worker2)
|
187
|
+
|
188
|
+
death.call
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'should remove the worker from the busy list' do
|
192
|
+
death.call
|
193
|
+
|
194
|
+
subject.wrapped_object.instance_variable_get(:@busy).should == []
|
195
|
+
end
|
196
|
+
|
197
|
+
it 'should have the new worker' do
|
198
|
+
death.call
|
199
|
+
|
200
|
+
subject.workers.should == [@worker1, @new_worker2]
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
describe 'when in SQS mode' do
|
205
|
+
before do
|
206
|
+
MicroQ.config['sqs?'] = true
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'should have the original items' do
|
210
|
+
death.call
|
211
|
+
|
212
|
+
subject.queue.should == @queue
|
213
|
+
subject.workers.should == [@worker1, @worker2]
|
214
|
+
end
|
215
|
+
end
|
147
216
|
end
|
148
217
|
end
|
149
218
|
end
|
@@ -0,0 +1,206 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MicroQ::Queue::Sqs do
|
4
|
+
let(:item) { { 'class' => 'MyWorker', 'args' => [4] } }
|
5
|
+
|
6
|
+
before do
|
7
|
+
@fetcher = mock('fetcher', :start! => true)
|
8
|
+
MicroQ::Fetcher::Sqs.stub(:new_link).and_return(@fetcher)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '.new' do
|
12
|
+
it 'should create three fetchers' do
|
13
|
+
MicroQ::Fetcher::Sqs.should_receive(:new_link).exactly(3).and_return(@fetcher)
|
14
|
+
|
15
|
+
subject
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should send the current actor along too' do
|
19
|
+
MicroQ::Fetcher::Sqs.should_receive(:new_link).exactly(3).with(anything, subject).and_return(@fetcher)
|
20
|
+
|
21
|
+
subject
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should start the fetcher' do
|
25
|
+
@fetcher.should_receive(:start!)
|
26
|
+
|
27
|
+
subject
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should have the fetchers' do
|
31
|
+
subject.fetchers.uniq.should == [@fetcher]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#receive_messages' do
|
36
|
+
let(:messages) { 3.times.map {|i| mock("message_#{i}")} }
|
37
|
+
|
38
|
+
it 'should have no messages' do
|
39
|
+
subject.messages.should == []
|
40
|
+
end
|
41
|
+
|
42
|
+
describe 'when messages have given back' do
|
43
|
+
before do
|
44
|
+
subject.receive_messages(messages.first(1))
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should have the messages' do
|
48
|
+
subject.messages.should == [messages.first]
|
49
|
+
end
|
50
|
+
|
51
|
+
describe 'when more messages have been received' do
|
52
|
+
before do
|
53
|
+
subject.receive_messages(messages.last(2))
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should have the messages' do
|
57
|
+
subject.messages.should == messages
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '#sync_push' do
|
64
|
+
before do
|
65
|
+
@fetchers = [:low, :default, :critical].collect do |name|
|
66
|
+
mock('MicroQ::Fetcher::Sqs : ' + name.to_s, :start! => nil).tap do |fetcher|
|
67
|
+
MicroQ::Fetcher::Sqs.stub(:new_link).with(name.to_s, anything).and_return(fetcher)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should add to the entries' do
|
73
|
+
@fetchers[1].should_receive(:add_message).with(item)
|
74
|
+
|
75
|
+
subject.sync_push(item)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should stringify the class' do
|
79
|
+
@fetchers[1].should_receive(:add_message).with(hash_including('class' => 'MyWorker'))
|
80
|
+
|
81
|
+
subject.sync_push(:class => MyWorker)
|
82
|
+
end
|
83
|
+
|
84
|
+
[:low, :default, :critical].each_with_index do |name, i|
|
85
|
+
describe "when the message has a queue named #{name}" do
|
86
|
+
before do
|
87
|
+
item['queue'] = name
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'should create the message on the right queue' do
|
91
|
+
@fetchers[i].should_receive(:add_message).with(item)
|
92
|
+
|
93
|
+
subject.sync_push(item)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe 'when given the \'when\' key' do
|
99
|
+
let(:worker) { [item, { 'when' => (Time.now + 100).to_i }] }
|
100
|
+
|
101
|
+
it 'should schedule the item for later' do
|
102
|
+
@fetchers[1].should_receive(:add_message).with(item, (Time.now + 100).to_i)
|
103
|
+
|
104
|
+
subject.sync_push(*worker)
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'should process the middleware chain' do
|
108
|
+
MicroQ.middleware.client.should_receive(:call) do |payload, options|
|
109
|
+
payload['class'].should == 'MyWorker'
|
110
|
+
payload['args'].should == [4]
|
111
|
+
options['when'].should == (Time.now + 100).to_i
|
112
|
+
end
|
113
|
+
|
114
|
+
subject.sync_push(*worker)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe 'when given the symbol :when key' do
|
119
|
+
let(:worker) { [item, { :when => (Time.now + 100).to_i }] }
|
120
|
+
|
121
|
+
it 'should schedule the item for later' do
|
122
|
+
@fetchers[1].should_receive(:add_message).with(item, (Time.now + 100).to_i)
|
123
|
+
|
124
|
+
subject.sync_push(*worker)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe 'client middleware' do
|
129
|
+
it 'should process the middleware chain' do
|
130
|
+
MicroQ.middleware.client.should_receive(:call) do |payload, opts|
|
131
|
+
payload['class'].should == 'MyWorker'
|
132
|
+
payload['args'].should == [4]
|
133
|
+
|
134
|
+
opts['when'].should == 'now'
|
135
|
+
end
|
136
|
+
|
137
|
+
subject.sync_push(item, 'when' => 'now')
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe '#push' do
|
143
|
+
before do
|
144
|
+
@async = mock(Celluloid::ActorProxy)
|
145
|
+
subject.stub(:async).and_return(@async)
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'should asynchronously push the item' do
|
149
|
+
@async.should_receive(:sync_push).with(item)
|
150
|
+
|
151
|
+
subject.push(item)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe '#dequeue' do
|
156
|
+
let(:items) { 2.times.map {|i| { 'class' => 'SqsWorker', 'args' => [i] }} }
|
157
|
+
let(:item) { items.first }
|
158
|
+
|
159
|
+
class SqsWorker
|
160
|
+
def perform(*)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe 'when there are messages' do
|
165
|
+
before do
|
166
|
+
subject.messages = items.map(&:dup)
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'should return the limited number of items' do
|
170
|
+
subject.dequeue(1).should == [items.last]
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'should remove the item from the list' do
|
174
|
+
subject.dequeue.should == items.reverse
|
175
|
+
|
176
|
+
subject.messages.should == []
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
describe 'when there are many messages' do
|
181
|
+
let(:messages) do
|
182
|
+
5.times.collect {|i|
|
183
|
+
item.dup.tap {|it| it['args'] = [i]}
|
184
|
+
}
|
185
|
+
end
|
186
|
+
|
187
|
+
before do
|
188
|
+
subject.messages = messages.map(&:dup)
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'should return up to the limit number of items' do
|
192
|
+
subject.dequeue(4).should == messages.last(4).reverse
|
193
|
+
|
194
|
+
subject.messages.should include(messages.first)
|
195
|
+
subject.dequeue.should == messages.first(1)
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'should remove the items' do
|
199
|
+
subject.dequeue.should == messages.reverse
|
200
|
+
subject.dequeue.should == []
|
201
|
+
|
202
|
+
subject.messages.should == []
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MicroQ::SqsClient, :aws => true do
|
4
|
+
let(:url) { 'http://the.queue/' }
|
5
|
+
|
6
|
+
subject { MicroQ::SqsClient.new('low') }
|
7
|
+
|
8
|
+
before do
|
9
|
+
MicroQ.config.env = 'dev-env'
|
10
|
+
|
11
|
+
@client = mock(AWS::SQS::Client, :receive_message => {}, :create_queue => {:queue_url => url})
|
12
|
+
AWS::SQS::Client.stub(:new).and_return(@client)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '.new' do
|
16
|
+
it 'should create the queue' do
|
17
|
+
@client.should_receive(:create_queue).and_return({})
|
18
|
+
|
19
|
+
subject
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should prefix the name with the environment' do
|
23
|
+
@client.should_receive(:create_queue).with(
|
24
|
+
:queue_name => 'dev-env_low'
|
25
|
+
).and_return({})
|
26
|
+
|
27
|
+
subject
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should have the url' do
|
31
|
+
subject.url.should == url
|
32
|
+
end
|
33
|
+
|
34
|
+
describe 'when the call fails' do
|
35
|
+
before do
|
36
|
+
@client.stub(:create_queue).and_raise
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should error' do
|
40
|
+
expect {
|
41
|
+
subject
|
42
|
+
}.to raise_error
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#messages' do
|
48
|
+
let(:messages) { subject.messages }
|
49
|
+
|
50
|
+
it 'should be an empty' do
|
51
|
+
messages.should == []
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should connect to the api for reading messages' do
|
55
|
+
@client.should_receive(:receive_message)
|
56
|
+
|
57
|
+
messages
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should have the queue url' do
|
61
|
+
@client.should_receive(:receive_message).with(hash_including(:queue_url => url))
|
62
|
+
|
63
|
+
messages
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should timeout after 10 seconds' do
|
67
|
+
@client.should_receive(:receive_message).with(hash_including(:wait_time_seconds => 10))
|
68
|
+
|
69
|
+
messages
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should request 10 items' do
|
73
|
+
@client.should_receive(:receive_message).with(hash_including(:max_number_of_messages => 10))
|
74
|
+
|
75
|
+
messages
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should make message available again after 5 minutes' do
|
79
|
+
@client.should_receive(:receive_message).with(hash_including(:visibility_timeout => 5 * 60))
|
80
|
+
|
81
|
+
messages
|
82
|
+
end
|
83
|
+
|
84
|
+
describe 'when messages are returned (body as json)' do
|
85
|
+
let(:response) do
|
86
|
+
{ :messages => 3.times.map {|i|
|
87
|
+
{
|
88
|
+
:body => {:id => i}.to_json,
|
89
|
+
:message_id => "id:#{i*5}",
|
90
|
+
:receipt_handle => "hand:#{i+10}"
|
91
|
+
}
|
92
|
+
}}
|
93
|
+
end
|
94
|
+
|
95
|
+
before do
|
96
|
+
@client.stub(:receive_message).and_return(response)
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should return the messages' do
|
100
|
+
messages.map {|m| m['id']}.should == [0, 1, 2]
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'should merge in the message id' do
|
104
|
+
messages.map {|m| m['sqs_id']}.should == ['id:0', 'id:5', 'id:10']
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'should merge in the message id' do
|
108
|
+
messages.map {|m| m['sqs_handle']}.should == ['hand:10', 'hand:11', 'hand:12']
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'should merge in the queue url' do
|
112
|
+
messages.map {|m| m['sqs_queue']}.uniq.should == [url]
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe '#messages_create' do
|
118
|
+
let(:message) { {:class => 'MyWorker', :args => ['hi']} }
|
119
|
+
let(:send_message) { subject.messages_create(message) }
|
120
|
+
|
121
|
+
before do
|
122
|
+
@response = {:message_id => '10'}
|
123
|
+
@client.stub(:send_message).and_return(@response)
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'should send the message' do
|
127
|
+
@client.should_receive(:send_message).and_return(@response)
|
128
|
+
|
129
|
+
send_message
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'should send it for the queue' do
|
133
|
+
@client.should_receive(:send_message).with(hash_including(:queue_url => url)).and_return(@response)
|
134
|
+
|
135
|
+
send_message
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'should send it for the queue' do
|
139
|
+
@client.should_receive(:send_message).with(hash_including(:message_body => message.to_json)).and_return(@response)
|
140
|
+
|
141
|
+
send_message
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'should not delay the message' do
|
145
|
+
@client.should_receive(:send_message).with(hash_excluding(:delay_seconds)).and_return(@response)
|
146
|
+
|
147
|
+
send_message
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'should return the message id' do
|
151
|
+
send_message.should == '10'
|
152
|
+
end
|
153
|
+
|
154
|
+
describe 'when the message is to be run later' do
|
155
|
+
before do
|
156
|
+
message['run_at'] = (Time.now + 60 * 60)
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'should set the delay for sqs' do
|
160
|
+
@client.should_receive(:send_message).with(hash_including(:delay_seconds => 60*60)).and_return(@response)
|
161
|
+
|
162
|
+
send_message
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -13,17 +13,34 @@ silence_warnings do
|
|
13
13
|
Redis = MockRedis
|
14
14
|
end
|
15
15
|
|
16
|
+
class MyWorker; end
|
17
|
+
|
16
18
|
RSpec.configure do |config|
|
17
19
|
config.treat_symbols_as_metadata_keys_with_true_values = true
|
18
20
|
config.run_all_when_everything_filtered = true
|
19
21
|
|
20
22
|
config.order = 'default'
|
21
23
|
|
24
|
+
config.before :all do
|
25
|
+
GC.disable
|
26
|
+
end
|
27
|
+
|
22
28
|
config.before :each do
|
23
29
|
MicroQ.send :clear
|
24
30
|
MicroQ.redis {|r| r.flushdb }
|
25
31
|
end
|
26
32
|
|
33
|
+
config.before :each, :aws => true do
|
34
|
+
require 'aws-sdk'
|
35
|
+
end
|
36
|
+
|
37
|
+
config.before :each, :middleware => true do
|
38
|
+
class WorkerClass; end
|
39
|
+
|
40
|
+
@worker = WorkerClass.new
|
41
|
+
@payload = { 'class' => 'WorkerClass', 'args' => [1, 2], 'queue' => 'a-queue'}
|
42
|
+
end
|
43
|
+
|
27
44
|
config.before :each, :active_record => true do
|
28
45
|
require 'active_record'
|
29
46
|
require 'sqlite3' # https://github.com/luislavena/sqlite3-ruby
|
@@ -52,11 +69,8 @@ RSpec.configure do |config|
|
|
52
69
|
@_db.rollback
|
53
70
|
end
|
54
71
|
|
55
|
-
config.
|
56
|
-
|
57
|
-
|
58
|
-
@worker = WorkerClass.new
|
59
|
-
@payload = { 'class' => 'WorkerClass', 'args' => [1, 2], 'queue' => 'a-queue'}
|
72
|
+
config.after :all do
|
73
|
+
GC.enable
|
60
74
|
end
|
61
75
|
end
|
62
76
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: micro_q
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Norton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-03-
|
11
|
+
date: 2013-03-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: celluloid
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: slop
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rake
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +66,20 @@ dependencies:
|
|
52
66
|
- - '>='
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: fuubar
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
84
|
name: rspec
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -150,9 +178,24 @@ dependencies:
|
|
150
178
|
- - '>='
|
151
179
|
- !ruby/object:Gem::Version
|
152
180
|
version: '0'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: aws-sdk
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - '>='
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
type: :development
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - '>='
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0'
|
153
195
|
description: ''
|
154
196
|
email: brian.nort@gmail.com
|
155
|
-
executables:
|
197
|
+
executables:
|
198
|
+
- microq
|
156
199
|
extensions: []
|
157
200
|
extra_rdoc_files: []
|
158
201
|
files:
|
@@ -164,9 +207,13 @@ files:
|
|
164
207
|
- LICENSE
|
165
208
|
- README.md
|
166
209
|
- Rakefile
|
210
|
+
- bin/microq
|
167
211
|
- lib/micro_q.rb
|
212
|
+
- lib/micro_q/cli.rb
|
168
213
|
- lib/micro_q/config.rb
|
169
214
|
- lib/micro_q/dsl.rb
|
215
|
+
- lib/micro_q/fetchers/sqs.rb
|
216
|
+
- lib/micro_q/inspect.rb
|
170
217
|
- lib/micro_q/manager.rb
|
171
218
|
- lib/micro_q/manager/default.rb
|
172
219
|
- lib/micro_q/methods/action_mailer.rb
|
@@ -189,7 +236,9 @@ files:
|
|
189
236
|
- lib/micro_q/queue.rb
|
190
237
|
- lib/micro_q/queue/default.rb
|
191
238
|
- lib/micro_q/queue/redis.rb
|
239
|
+
- lib/micro_q/queue/sqs.rb
|
192
240
|
- lib/micro_q/redis.rb
|
241
|
+
- lib/micro_q/sqs_client.rb
|
193
242
|
- lib/micro_q/statistics/base.rb
|
194
243
|
- lib/micro_q/statistics/default.rb
|
195
244
|
- lib/micro_q/statistics/redis.rb
|
@@ -203,6 +252,7 @@ files:
|
|
203
252
|
- spec/helpers/queues_examples.rb
|
204
253
|
- spec/lib/config_spec.rb
|
205
254
|
- spec/lib/dsl_spec.rb
|
255
|
+
- spec/lib/fetchers/sqs_spec.rb
|
206
256
|
- spec/lib/manager/default_spec.rb
|
207
257
|
- spec/lib/methods/action_mailer_spec.rb
|
208
258
|
- spec/lib/methods/active_record_spec.rb
|
@@ -221,6 +271,8 @@ files:
|
|
221
271
|
- spec/lib/proxies/instance_spec.rb
|
222
272
|
- spec/lib/queue/default_spec.rb
|
223
273
|
- spec/lib/queue/redis_spec.rb
|
274
|
+
- spec/lib/queue/sqs_spec.rb
|
275
|
+
- spec/lib/sqs_client_spec.rb
|
224
276
|
- spec/lib/statistics/default_spec.rb
|
225
277
|
- spec/lib/statistics/redis_spec.rb
|
226
278
|
- spec/lib/util_spec.rb
|
@@ -255,6 +307,7 @@ test_files:
|
|
255
307
|
- spec/helpers/queues_examples.rb
|
256
308
|
- spec/lib/config_spec.rb
|
257
309
|
- spec/lib/dsl_spec.rb
|
310
|
+
- spec/lib/fetchers/sqs_spec.rb
|
258
311
|
- spec/lib/manager/default_spec.rb
|
259
312
|
- spec/lib/methods/action_mailer_spec.rb
|
260
313
|
- spec/lib/methods/active_record_spec.rb
|
@@ -273,6 +326,8 @@ test_files:
|
|
273
326
|
- spec/lib/proxies/instance_spec.rb
|
274
327
|
- spec/lib/queue/default_spec.rb
|
275
328
|
- spec/lib/queue/redis_spec.rb
|
329
|
+
- spec/lib/queue/sqs_spec.rb
|
330
|
+
- spec/lib/sqs_client_spec.rb
|
276
331
|
- spec/lib/statistics/default_spec.rb
|
277
332
|
- spec/lib/statistics/redis_spec.rb
|
278
333
|
- spec/lib/util_spec.rb
|