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.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/.ruby-version +1 -0
  3. data/.travis.yml +9 -1
  4. data/README.md +5 -2
  5. data/lib/micro_q/config.rb +1 -0
  6. data/lib/micro_q/dsl.rb +41 -16
  7. data/lib/micro_q/manager/default.rb +53 -7
  8. data/lib/micro_q/middleware/chain.rb +15 -2
  9. data/lib/micro_q/middleware/client/statistics.rb +22 -0
  10. data/lib/micro_q/middleware/server/retry.rb +20 -5
  11. data/lib/micro_q/middleware/server/statistics.rb +22 -0
  12. data/lib/micro_q/middleware/server/timeout.rb +19 -0
  13. data/lib/micro_q/middleware/util.rb +21 -0
  14. data/lib/micro_q/queue/default.rb +25 -18
  15. data/lib/micro_q/queue/redis.rb +2 -2
  16. data/lib/micro_q/statistics/base.rb +15 -0
  17. data/lib/micro_q/statistics/default.rb +18 -0
  18. data/lib/micro_q/statistics/redis.rb +23 -0
  19. data/lib/micro_q/version.rb +1 -1
  20. data/lib/micro_q/worker/standard.rb +20 -10
  21. data/lib/micro_q.rb +25 -3
  22. data/micro_q.gemspec +1 -1
  23. data/spec/helpers/methods_examples.rb +1 -1
  24. data/spec/helpers/queues_examples.rb +4 -4
  25. data/spec/lib/config_spec.rb +4 -0
  26. data/spec/lib/dsl_spec.rb +14 -2
  27. data/spec/lib/manager/default_spec.rb +90 -16
  28. data/spec/lib/methods/action_mailer_spec.rb +2 -2
  29. data/spec/lib/methods/active_record_spec.rb +2 -2
  30. data/spec/lib/methods/class_spec.rb +2 -2
  31. data/spec/lib/methods/instance_spec.rb +2 -2
  32. data/spec/lib/micro_q_spec.rb +13 -2
  33. data/spec/lib/middleware/chain_spec.rb +83 -6
  34. data/spec/lib/middleware/client/statistics_spec.rb +53 -0
  35. data/spec/lib/middleware/server/connection_spec.rb +1 -1
  36. data/spec/lib/middleware/server/retry_spec.rb +33 -4
  37. data/spec/lib/middleware/server/statistics_spec.rb +53 -0
  38. data/spec/lib/middleware/server/timeout_spec.rb +40 -0
  39. data/spec/lib/proxies/base_spec.rb +2 -2
  40. data/spec/lib/proxies/instance_spec.rb +1 -1
  41. data/spec/lib/queue/default_spec.rb +2 -4
  42. data/spec/lib/queue/redis_spec.rb +2 -4
  43. data/spec/lib/statistics/default_spec.rb +73 -0
  44. data/spec/lib/statistics/redis_spec.rb +73 -0
  45. data/spec/lib/util_spec.rb +1 -1
  46. data/spec/lib/worker/standard_spec.rb +26 -11
  47. data/spec/lib/wrappers/action_mailer_spec.rb +2 -2
  48. data/spec/spec_helper.rb +1 -1
  49. metadata +49 -58
  50. data/lib/micro_q/methods.rb +0 -7
  51. 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: 2.0.0
20
+ - rvm: rbx-nightly-19mode
21
+ branches:
22
+ only:
23
+ - master
24
+ - /^((feature)|(hotfix))\/.+/
data/README.md CHANGED
@@ -1,4 +1,7 @@
1
- # MicroQ [![Build Status](https://travis-ci.org/bnorton/micro_q.png)](https://travis-ci.org/bnorton/micro_q)
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
@@ -17,6 +17,7 @@ module MicroQ
17
17
  'manager' => Manager::Default,
18
18
  'worker' => Worker::Standard,
19
19
  'queue' => Queue::Default,
20
+ 'statistics' => Statistics::Default,
20
21
  'redis_pool' => { :size => 15, :timeout => 1 },
21
22
  'redis' => { :host => 'localhost', :port => 6379 }
22
23
  }
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
- def worker(*opts)
4
- self.class_eval do
5
- def self.microq_options
6
- @microq_options ||= { :methods => [:perform] }
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
- if Hash === opts.last
11
- self.microq_options.merge!(opts.pop)
12
- end
13
-
14
- async_methods = self.microq_options[:methods] |= opts.flatten
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
- self.class_eval do
17
- async_methods.each do |method|
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
- attr_reader :queue, :workers
20
+ # Invoke this when the Queue or Worker pool dies
21
+ exit_handler :reinitialize
21
22
 
22
- def initialize
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.idle_size
26
+ count = workers.size
29
27
 
30
28
  if (messages = queue.dequeue(count)).any?
31
29
  messages.each do |message|
32
- workers.perform!(message)
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['retried'] ||= { 'count' => 0 }
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
- klass = item['class'] = item['class'].to_s
56
+ item['class'] = item['class'].to_s
57
57
 
58
- MicroQ.middleware.client.call(klass, item, options) do
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
- idx = 0
77
+ opts = { :i => 0, :limit => limit}
78
78
  [].tap do |items|
79
- entries.each do |entry|
80
- items << entry unless (idx += 1) > limit
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
  #
@@ -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
- klass = item['class'] = item['class'].to_s
44
+ item['class'] = item['class'].to_s
45
45
 
46
- MicroQ.middleware.client.call(klass, item, options) do
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,15 @@
1
+ module MicroQ
2
+ module Statistics
3
+ class Base
4
+ attr_reader :increment
5
+
6
+ def self.stats
7
+ yield instance
8
+ end
9
+
10
+ def self.instance
11
+ @instance ||= new
12
+ end
13
+ end
14
+ end
15
+ end
@@ -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
@@ -1,6 +1,6 @@
1
1
  module MicroQ
2
2
  MAJOR = 0
3
- MINOR = 7
3
+ MINOR = 8
4
4
  POINT = 0
5
5
 
6
6
  VERSION = [MAJOR, MINOR, POINT].join('.')
@@ -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 paramater as a list of ids)
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 perform(message)
22
- klass = MicroQ::Util.constantize(message['class'].to_s)
21
+ def initialize(manager)
22
+ @manager = manager
23
+ end
23
24
 
24
- loader = message['loader'] ||= { 'method' => 'new' }
25
- klass = klass.send(loader['method'], *loader['args']) if loader['method']
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
- value = nil
31
-
32
- MicroQ.middleware.server.call(klass, message) do
33
- value = klass.send(method, *args)
31
+ defer do
32
+ MicroQ.middleware.server.call(klass, message) do
33
+ klass.send(method, *args)
34
+ end
34
35
  end
35
36
 
36
- value
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"
@@ -1,4 +1,4 @@
1
- shared_examples_for "a_worker" do |method|
1
+ shared_examples_for 'a_worker' do |method|
2
2
  describe "additions (#{method})" do
3
3
  it 'should add an async proxy' do
4
4
  subject.respond_to?(:async).should == true
@@ -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 |w, payload|
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
@@ -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