micro_q 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.ruby-version +1 -0
- data/.travis.yml +9 -1
- data/README.md +5 -2
- data/lib/micro_q/config.rb +1 -0
- data/lib/micro_q/dsl.rb +41 -16
- data/lib/micro_q/manager/default.rb +53 -7
- data/lib/micro_q/middleware/chain.rb +15 -2
- data/lib/micro_q/middleware/client/statistics.rb +22 -0
- data/lib/micro_q/middleware/server/retry.rb +20 -5
- data/lib/micro_q/middleware/server/statistics.rb +22 -0
- data/lib/micro_q/middleware/server/timeout.rb +19 -0
- data/lib/micro_q/middleware/util.rb +21 -0
- data/lib/micro_q/queue/default.rb +25 -18
- data/lib/micro_q/queue/redis.rb +2 -2
- data/lib/micro_q/statistics/base.rb +15 -0
- data/lib/micro_q/statistics/default.rb +18 -0
- data/lib/micro_q/statistics/redis.rb +23 -0
- data/lib/micro_q/version.rb +1 -1
- data/lib/micro_q/worker/standard.rb +20 -10
- data/lib/micro_q.rb +25 -3
- data/micro_q.gemspec +1 -1
- data/spec/helpers/methods_examples.rb +1 -1
- data/spec/helpers/queues_examples.rb +4 -4
- data/spec/lib/config_spec.rb +4 -0
- data/spec/lib/dsl_spec.rb +14 -2
- data/spec/lib/manager/default_spec.rb +90 -16
- data/spec/lib/methods/action_mailer_spec.rb +2 -2
- data/spec/lib/methods/active_record_spec.rb +2 -2
- data/spec/lib/methods/class_spec.rb +2 -2
- data/spec/lib/methods/instance_spec.rb +2 -2
- data/spec/lib/micro_q_spec.rb +13 -2
- data/spec/lib/middleware/chain_spec.rb +83 -6
- data/spec/lib/middleware/client/statistics_spec.rb +53 -0
- data/spec/lib/middleware/server/connection_spec.rb +1 -1
- data/spec/lib/middleware/server/retry_spec.rb +33 -4
- data/spec/lib/middleware/server/statistics_spec.rb +53 -0
- data/spec/lib/middleware/server/timeout_spec.rb +40 -0
- data/spec/lib/proxies/base_spec.rb +2 -2
- data/spec/lib/proxies/instance_spec.rb +1 -1
- data/spec/lib/queue/default_spec.rb +2 -4
- data/spec/lib/queue/redis_spec.rb +2 -4
- data/spec/lib/statistics/default_spec.rb +73 -0
- data/spec/lib/statistics/redis_spec.rb +73 -0
- data/spec/lib/util_spec.rb +1 -1
- data/spec/lib/worker/standard_spec.rb +26 -11
- data/spec/lib/wrappers/action_mailer_spec.rb +2 -2
- data/spec/spec_helper.rb +1 -1
- metadata +49 -58
- data/lib/micro_q/methods.rb +0 -7
- data/lib/micro_q/wrappers.rb +0 -1
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5d7397239d88fe8ba5027ca54e052af6ee286e32
|
4
|
+
data.tar.gz: e52f3922fd037146a570208025aaf64451aa600c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2318f4b75ccaaa0412809273013d7d8b563356b3cafd0219ed26b2bad66ccd3fd2c753fa8b36b76dade486182ccb12394c6679b2df4ea5edf734e66dcb2d7805
|
7
|
+
data.tar.gz: 9b989f109f14acaea6742c95050701aa81631137923a1896c0b43f88a9f088179bf8826cff482205cbff14e228a8e9aefc2c82a3ead9b7762469006275050a9b
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.0.0-p0@micro_q
|
data/.travis.yml
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
3
|
- 1.9.3
|
4
|
+
- 1.9.2
|
4
5
|
- rbx-19mode
|
6
|
+
- rbx-nightly-19mode
|
5
7
|
- 2.0.0
|
6
8
|
branches:
|
7
9
|
only:
|
@@ -12,5 +14,11 @@ notifications:
|
|
12
14
|
- brian.nort@gmail.com
|
13
15
|
matrix:
|
14
16
|
allow_failures:
|
17
|
+
- rvm: 1.9.3
|
18
|
+
- rvm: 1.9.2
|
15
19
|
- rvm: rbx-19mode
|
16
|
-
- rvm:
|
20
|
+
- rvm: rbx-nightly-19mode
|
21
|
+
branches:
|
22
|
+
only:
|
23
|
+
- master
|
24
|
+
- /^((feature)|(hotfix))\/.+/
|
data/README.md
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
-
# MicroQ
|
1
|
+
# MicroQ
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/bnorton/micro_q.png)](https://travis-ci.org/bnorton/micro_q)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/bnorton/micro_q.png)](https://codeclimate.com/github/bnorton/micro_q)
|
2
5
|
|
3
6
|
MicroQ is a per-process asynchronous background queue.
|
4
7
|
|
@@ -42,7 +45,7 @@ MyWorker.async_update(:user_id => user.id)
|
|
42
45
|
|
43
46
|
###Advanced
|
44
47
|
|
45
|
-
Safely using an ActiveRecord instance via the Custom Loader API
|
48
|
+
Safely using an ActiveRecord instance via the [Custom Loader](https://github.com/bnorton/micro_q/wiki/Loaders) API
|
46
49
|
```ruby
|
47
50
|
# app/models/user.rb
|
48
51
|
class User < Activerecord::Base
|
data/lib/micro_q/config.rb
CHANGED
data/lib/micro_q/dsl.rb
CHANGED
@@ -1,28 +1,53 @@
|
|
1
1
|
module MicroQ
|
2
|
+
##
|
3
|
+
# Convenience methods for calling methods asynchronously
|
4
|
+
# Adds async_perform by default
|
5
|
+
#
|
6
|
+
# Usage
|
7
|
+
# class MyWorker
|
8
|
+
# worker :update, :queue => 'non-default'
|
9
|
+
#
|
10
|
+
# def update
|
11
|
+
# end
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# MyWorker.async_update
|
15
|
+
# is the same as
|
16
|
+
# MyWorker.new.async(:queue => 'non-default').update
|
17
|
+
#
|
2
18
|
module DSL
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
19
|
+
##
|
20
|
+
# For each of the methods given to the Object.worker method
|
21
|
+
# define the async_ prefixed version for convenience
|
22
|
+
#
|
23
|
+
def self.attach_async_methods(target, opts)
|
24
|
+
target.class_eval do
|
25
|
+
(target.microq_options[:methods] |= opts.flatten).each do |method|
|
26
|
+
target.define_singleton_method(:"async_#{method}") do |*args|
|
27
|
+
MicroQ::Proxy::Instance.new(
|
28
|
+
target.microq_options.dup.merge(:class => self)
|
29
|
+
).send(method, *args)
|
30
|
+
end unless respond_to?(:"async_#{method}")
|
7
31
|
end
|
8
32
|
end
|
33
|
+
end
|
9
34
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
35
|
+
module ClassMethods
|
36
|
+
def worker(*opts)
|
37
|
+
self.class_eval do
|
38
|
+
def self.microq_options
|
39
|
+
@microq_options ||= { :methods => [:perform] }
|
40
|
+
end
|
41
|
+
end
|
15
42
|
|
16
|
-
|
17
|
-
|
18
|
-
async_method = :"async_#{method}"
|
19
|
-
define_singleton_method(async_method) do |*args|
|
20
|
-
MicroQ::Proxy::Instance.new(:class => self).send(method, *args)
|
21
|
-
end unless respond_to?(async_method)
|
43
|
+
if Hash === opts.last
|
44
|
+
self.microq_options.merge!(opts.pop)
|
22
45
|
end
|
46
|
+
|
47
|
+
DSL.attach_async_methods(self, opts)
|
23
48
|
end
|
24
49
|
end
|
25
50
|
end
|
26
51
|
end
|
27
52
|
|
28
|
-
Object.send(:extend, MicroQ::DSL)
|
53
|
+
Object.send(:extend, MicroQ::DSL::ClassMethods)
|
@@ -17,24 +17,70 @@ module MicroQ
|
|
17
17
|
class Default
|
18
18
|
include Celluloid
|
19
19
|
|
20
|
-
|
20
|
+
# Invoke this when the Queue or Worker pool dies
|
21
|
+
exit_handler :reinitialize
|
21
22
|
|
22
|
-
|
23
|
-
@queue = MicroQ.config.queue.new
|
24
|
-
@workers = MicroQ.config.worker.pool(:size => MicroQ.config.workers)
|
25
|
-
end
|
23
|
+
attr_reader :queue, :workers
|
26
24
|
|
27
25
|
def start
|
28
|
-
count = workers.
|
26
|
+
count = workers.size
|
29
27
|
|
30
28
|
if (messages = queue.dequeue(count)).any?
|
31
29
|
messages.each do |message|
|
32
|
-
workers.
|
30
|
+
worker = workers.pop
|
31
|
+
@busy << worker
|
32
|
+
|
33
|
+
worker.perform!(message)
|
33
34
|
end
|
34
35
|
end
|
35
36
|
|
36
37
|
after(2) { start }
|
37
38
|
end
|
39
|
+
|
40
|
+
def work_done(worker)
|
41
|
+
@busy.delete(worker)
|
42
|
+
workers.push(worker)
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# Handle init/death of the Queue or the Worker pool
|
47
|
+
#
|
48
|
+
def reinitialize(*)
|
49
|
+
kill_all and return if self.class.shutdown?
|
50
|
+
|
51
|
+
unless @queue && @queue.alive?
|
52
|
+
@queue = MicroQ.config.queue.new_link
|
53
|
+
end
|
54
|
+
|
55
|
+
@busy ||= []
|
56
|
+
|
57
|
+
build_missing_workers
|
58
|
+
end
|
59
|
+
|
60
|
+
alias initialize reinitialize
|
61
|
+
|
62
|
+
# Don't shrink the pool if the config changes
|
63
|
+
def build_missing_workers
|
64
|
+
@workers ||= []
|
65
|
+
|
66
|
+
workers.reject! {|worker| !worker.alive? }
|
67
|
+
|
68
|
+
[MicroQ.config.workers - (workers.size + @busy.size), 0].max.times do
|
69
|
+
workers << MicroQ.config.worker.new_link(current_actor)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def kill_all
|
74
|
+
(@workers + @busy).each {|w| w.terminate if w.alive? }
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.shutdown?
|
78
|
+
!!@shutdown
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.shutdown!
|
82
|
+
@shutdown = true
|
83
|
+
end
|
38
84
|
end
|
39
85
|
end
|
40
86
|
end
|
@@ -1,5 +1,10 @@
|
|
1
|
+
require 'micro_q/middleware/util'
|
1
2
|
require 'micro_q/middleware/server/retry'
|
2
3
|
require 'micro_q/middleware/server/connection'
|
4
|
+
require 'micro_q/middleware/server/timeout'
|
5
|
+
require 'micro_q/middleware/server/statistics'
|
6
|
+
|
7
|
+
require 'micro_q/middleware/client/statistics'
|
3
8
|
|
4
9
|
module MicroQ
|
5
10
|
module Middleware
|
@@ -35,12 +40,14 @@ module MicroQ
|
|
35
40
|
end
|
36
41
|
|
37
42
|
class Base
|
38
|
-
attr_reader :entries
|
39
|
-
|
40
43
|
def initialize
|
41
44
|
clear
|
42
45
|
end
|
43
46
|
|
47
|
+
def entries
|
48
|
+
[*@entries, @last].compact
|
49
|
+
end
|
50
|
+
|
44
51
|
##
|
45
52
|
# Add any number of entries to the middleware chain
|
46
53
|
#
|
@@ -90,7 +97,9 @@ module MicroQ
|
|
90
97
|
|
91
98
|
class Server < Base
|
92
99
|
def initialize
|
100
|
+
@last = MicroQ::Middleware::Server::Statistics
|
93
101
|
@entries = [
|
102
|
+
MicroQ::Middleware::Server::Timeout,
|
94
103
|
MicroQ::Middleware::Server::Retry,
|
95
104
|
MicroQ::Middleware::Server::Connection
|
96
105
|
]
|
@@ -98,6 +107,10 @@ module MicroQ
|
|
98
107
|
end
|
99
108
|
|
100
109
|
class Client < Base
|
110
|
+
def initialize
|
111
|
+
@last = MicroQ::Middleware::Client::Statistics
|
112
|
+
super
|
113
|
+
end
|
101
114
|
end
|
102
115
|
end
|
103
116
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module MicroQ
|
2
|
+
module Middleware
|
3
|
+
module Client
|
4
|
+
class Statistics
|
5
|
+
include MicroQ::Middleware::Util
|
6
|
+
|
7
|
+
ENQUEUED = proc {|klass| klass ? "messages:#{klass}:enqueued" : 'messages:enqueued' }
|
8
|
+
|
9
|
+
def call(message, options)
|
10
|
+
stats(message)
|
11
|
+
yield
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def stats(msg)
|
17
|
+
stats_incr(msg, ENQUEUED, "queues:#{msg['queue']}:enqueued")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -11,21 +11,36 @@ module MicroQ
|
|
11
11
|
# when: The time at which the message will be retried again
|
12
12
|
#
|
13
13
|
class Retry
|
14
|
+
include MicroQ::Middleware::Util
|
15
|
+
|
16
|
+
RETRY = proc {|klass| klass ? "messages:#{klass}:retry" : 'messages:retry' }
|
17
|
+
|
14
18
|
def call(worker, message)
|
15
19
|
yield
|
16
20
|
rescue Exception => e
|
17
21
|
raise e unless message['retry']
|
18
22
|
|
19
|
-
message
|
20
|
-
|
21
|
-
message['retried']['count'] += 1
|
22
|
-
message['retried']['at'] = Time.now
|
23
|
-
message['retried']['when'] = (Time.now + 15).to_f
|
23
|
+
retried!(message)
|
24
|
+
stats(message)
|
24
25
|
|
25
26
|
MicroQ.push(message, message['retried'])
|
26
27
|
|
27
28
|
raise e
|
28
29
|
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def retried!(msg)
|
34
|
+
msg['retried'] ||= { 'count' => 0 }
|
35
|
+
|
36
|
+
msg['retried']['count'] += 1
|
37
|
+
msg['retried']['at'] = Time.now
|
38
|
+
msg['retried']['when'] = (Time.now + 15).to_f
|
39
|
+
end
|
40
|
+
|
41
|
+
def stats(msg)
|
42
|
+
stats_incr(msg, RETRY, "queues:#{msg['queue']}:retry")
|
43
|
+
end
|
29
44
|
end
|
30
45
|
end
|
31
46
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module MicroQ
|
2
|
+
module Middleware
|
3
|
+
module Server
|
4
|
+
class Statistics
|
5
|
+
include MicroQ::Middleware::Util
|
6
|
+
|
7
|
+
PERFORMED = proc {|klass| klass ? "messages:#{klass}:performed" : 'messages:performed' }
|
8
|
+
|
9
|
+
def call(_, message)
|
10
|
+
stats(message)
|
11
|
+
yield
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def stats(msg)
|
17
|
+
stats_incr(msg, PERFORMED, "queues:#{msg['queue']}:performed")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module MicroQ
|
2
|
+
module Middleware
|
3
|
+
module Server
|
4
|
+
class Timeout
|
5
|
+
DEFAULT = 10 * 60
|
6
|
+
|
7
|
+
include ::Timeout
|
8
|
+
|
9
|
+
def call(_, message)
|
10
|
+
time = (time = message['timeout'].to_i) > 0 ? time : DEFAULT
|
11
|
+
|
12
|
+
timeout(time) do
|
13
|
+
yield
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module MicroQ
|
2
|
+
module Middleware
|
3
|
+
module Util
|
4
|
+
def stats_incr(msg, generator, *keys)
|
5
|
+
statistics do |stats|
|
6
|
+
stats.incr(
|
7
|
+
generator.call,
|
8
|
+
generator.call(msg['class']),
|
9
|
+
*keys.flatten
|
10
|
+
)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def statistics
|
15
|
+
MicroQ::Statistics::Default.stats do |stats|
|
16
|
+
yield stats
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -53,9 +53,9 @@ module MicroQ
|
|
53
53
|
#
|
54
54
|
def sync_push(item, options={})
|
55
55
|
item, options = MicroQ::Util.stringify(item, options)
|
56
|
-
|
56
|
+
item['class'] = item['class'].to_s
|
57
57
|
|
58
|
-
MicroQ.middleware.client.call(
|
58
|
+
MicroQ.middleware.client.call(item, options) do
|
59
59
|
if (time = options['when'])
|
60
60
|
@later.push(
|
61
61
|
'when' => time.to_f,
|
@@ -74,23 +74,10 @@ module MicroQ
|
|
74
74
|
def dequeue(limit = 30)
|
75
75
|
return [] if limit == 0
|
76
76
|
|
77
|
-
|
77
|
+
opts = { :i => 0, :limit => limit}
|
78
78
|
[].tap do |items|
|
79
|
-
|
80
|
-
|
81
|
-
end if entries.any?
|
82
|
-
|
83
|
-
items.each {|i| entries.delete(i) }
|
84
|
-
|
85
|
-
available = later.select {|entry| entry['when'] < Time.now.to_f }
|
86
|
-
|
87
|
-
if available.any?
|
88
|
-
available.each do |entry|
|
89
|
-
items << entry['worker'] unless (idx += 1) > limit
|
90
|
-
end
|
91
|
-
|
92
|
-
available.each {|a| later.delete(a) }
|
93
|
-
end
|
79
|
+
dequeue_entries!(items, opts)
|
80
|
+
dequeue_later!(items, opts)
|
94
81
|
end
|
95
82
|
end
|
96
83
|
|
@@ -107,6 +94,26 @@ module MicroQ
|
|
107
94
|
|
108
95
|
private
|
109
96
|
|
97
|
+
def dequeue_entries!(items, options)
|
98
|
+
entries.each do |entry|
|
99
|
+
items << entry unless (options[:i] += 1) > options[:limit]
|
100
|
+
end if entries.any?
|
101
|
+
|
102
|
+
items.each {|i| entries.delete(i) }
|
103
|
+
end
|
104
|
+
|
105
|
+
def dequeue_later!(items, options)
|
106
|
+
available = later.select {|entry| entry['when'] < Time.now.to_f }
|
107
|
+
|
108
|
+
if available.any?
|
109
|
+
available.each do |entry|
|
110
|
+
items << entry['worker'] unless (options[:i] += 1) > options[:limit]
|
111
|
+
end
|
112
|
+
|
113
|
+
available.each {|a| later.delete(a) }
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
110
117
|
##
|
111
118
|
# Parse the entries back into the queue from the filesystem
|
112
119
|
#
|
data/lib/micro_q/queue/redis.rb
CHANGED
@@ -41,9 +41,9 @@ module MicroQ
|
|
41
41
|
|
42
42
|
def sync_push(item, options = {})
|
43
43
|
item, options = MicroQ::Util.stringify(item, options)
|
44
|
-
|
44
|
+
item['class'] = item['class'].to_s
|
45
45
|
|
46
|
-
MicroQ.middleware.client.call(
|
46
|
+
MicroQ.middleware.client.call(item, options) do
|
47
47
|
json = JSON.dump(item)
|
48
48
|
|
49
49
|
MicroQ.redis do |r|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module MicroQ
|
2
|
+
module Statistics
|
3
|
+
class Default < Base
|
4
|
+
def initialize
|
5
|
+
@increment = Hash.new { 0 }
|
6
|
+
@increment_mutex = Mutex.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def incr(*keys)
|
10
|
+
@increment_mutex.synchronize do
|
11
|
+
keys.flatten.each do |key|
|
12
|
+
@increment[key.to_s] += 1
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module MicroQ
|
2
|
+
module Statistics
|
3
|
+
class Redis < Base
|
4
|
+
INCR = 'statistics:increment'
|
5
|
+
|
6
|
+
def increment
|
7
|
+
MicroQ.redis do |r|
|
8
|
+
r.hgetall(INCR)
|
9
|
+
end.each_with_object({}) do |(k, v), hash|
|
10
|
+
hash[k] = v.to_i
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def incr(*keys)
|
15
|
+
MicroQ.redis do |r| r.pipelined {
|
16
|
+
keys.flatten.each do |key|
|
17
|
+
r.hincrby(INCR, key, 1)
|
18
|
+
end
|
19
|
+
} end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/micro_q/version.rb
CHANGED
@@ -12,28 +12,38 @@ module MicroQ
|
|
12
12
|
# A minimal message: (Calls the perform method with zero arguments)
|
13
13
|
# { :class => 'MyWorker' }
|
14
14
|
#
|
15
|
-
# A more complex message: (Calls the update_data with a single
|
15
|
+
# A more complex message: (Calls the update_data with a single parameter as a list of ids)
|
16
16
|
# { :class => 'MyUpdater', 'method' => 'update_data', :args => [[2, 6,74, 198]]}
|
17
17
|
#
|
18
18
|
class Standard
|
19
19
|
include Celluloid
|
20
20
|
|
21
|
-
def
|
22
|
-
|
21
|
+
def initialize(manager)
|
22
|
+
@manager = manager
|
23
|
+
end
|
23
24
|
|
24
|
-
|
25
|
-
klass =
|
25
|
+
def perform(message)
|
26
|
+
klass = fetch_klass(message)
|
26
27
|
|
27
28
|
method = message['method'] || 'perform'
|
28
29
|
args = message['args']
|
29
30
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
defer do
|
32
|
+
MicroQ.middleware.server.call(klass, message) do
|
33
|
+
klass.send(method, *args)
|
34
|
+
end
|
34
35
|
end
|
35
36
|
|
36
|
-
|
37
|
+
@manager.work_done!(current_actor)
|
38
|
+
end
|
39
|
+
|
40
|
+
def fetch_klass(message)
|
41
|
+
klass = MicroQ::Util.constantize(message['class'].to_s)
|
42
|
+
|
43
|
+
loader = message['loader'] ||= { 'method' => 'new' }
|
44
|
+
klass = klass.send(loader['method'], *loader['args']) if loader['method']
|
45
|
+
|
46
|
+
klass
|
37
47
|
end
|
38
48
|
end
|
39
49
|
end
|
data/lib/micro_q.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'timeout'
|
1
2
|
require 'celluloid'
|
2
3
|
require 'connection_pool'
|
3
4
|
require 'redis'
|
@@ -19,6 +20,10 @@ module MicroQ
|
|
19
20
|
config.middleware
|
20
21
|
end
|
21
22
|
|
23
|
+
def self.stats(&block)
|
24
|
+
config.statistics.stats(&block)
|
25
|
+
end
|
26
|
+
|
22
27
|
def self.start
|
23
28
|
manager
|
24
29
|
end
|
@@ -43,11 +48,28 @@ module MicroQ
|
|
43
48
|
end
|
44
49
|
|
45
50
|
require 'micro_q/middleware'
|
46
|
-
require 'micro_q/wrappers'
|
47
|
-
require 'micro_q/methods'
|
48
|
-
require 'micro_q/dsl'
|
49
51
|
require 'micro_q/proxies'
|
52
|
+
require 'micro_q/dsl'
|
50
53
|
require 'micro_q/worker'
|
51
54
|
require 'micro_q/queue'
|
52
55
|
|
53
56
|
require 'micro_q/redis'
|
57
|
+
|
58
|
+
require 'micro_q/wrappers/action_mailer'
|
59
|
+
|
60
|
+
# add Class and Instance methods first then
|
61
|
+
# override with additional extensions
|
62
|
+
|
63
|
+
require 'micro_q/methods/class'
|
64
|
+
require 'micro_q/methods/instance'
|
65
|
+
require 'micro_q/methods/active_record'
|
66
|
+
require 'micro_q/methods/action_mailer'
|
67
|
+
|
68
|
+
require 'micro_q/statistics/base'
|
69
|
+
require 'micro_q/statistics/default'
|
70
|
+
require 'micro_q/statistics/redis'
|
71
|
+
|
72
|
+
# There is a better way coming soon 2/18/13
|
73
|
+
at_exit do
|
74
|
+
MicroQ::Manager::Default.shutdown!
|
75
|
+
end
|
data/micro_q.gemspec
CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |gem|
|
|
17
17
|
gem.test_files = gem.files.grep(%r{^spec/})
|
18
18
|
gem.require_paths = %w(lib)
|
19
19
|
|
20
|
-
gem.add_dependency "celluloid"
|
20
|
+
gem.add_dependency "celluloid", '~> 0.12.0'
|
21
21
|
gem.add_dependency "redis"
|
22
22
|
gem.add_dependency "connection_pool"
|
23
23
|
gem.add_development_dependency "rake"
|
@@ -24,14 +24,14 @@ shared_examples_for 'Queue#sync_push' do
|
|
24
24
|
|
25
25
|
describe 'client middleware' do
|
26
26
|
it 'should process the middleware chain' do
|
27
|
-
MicroQ.middleware.client.should_receive(:call) do |
|
28
|
-
w.should == 'MyWorker'
|
29
|
-
|
27
|
+
MicroQ.middleware.client.should_receive(:call) do |payload, opts|
|
30
28
|
payload['class'].should == 'MyWorker'
|
31
29
|
payload['args'].should == [4]
|
30
|
+
|
31
|
+
opts['when'].should == 'now'
|
32
32
|
end
|
33
33
|
|
34
|
-
subject.sync_push(item)
|
34
|
+
subject.sync_push(item, 'when' => 'now')
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
data/spec/lib/config_spec.rb
CHANGED
@@ -63,5 +63,9 @@ describe MicroQ::Config do
|
|
63
63
|
it 'should have the standard worker' do
|
64
64
|
subject.worker.should == MicroQ::Worker::Standard
|
65
65
|
end
|
66
|
+
|
67
|
+
it 'should have the default statistics' do
|
68
|
+
subject.statistics.should == MicroQ::Statistics::Default
|
69
|
+
end
|
66
70
|
end
|
67
71
|
end
|