micro_q 0.7.0 → 0.8.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/.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
|
+
[](https://travis-ci.org/bnorton/micro_q)
|
4
|
+
[](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
|