resqued 0.8.4 → 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,73 @@
1
+ module Resqued
2
+ class MasterState
3
+ def initialize
4
+ @listeners_created = 0
5
+ @listener_states = {}
6
+ end
7
+
8
+ # Public: When starting fresh, from command-line options, assign the initial values.
9
+ def init(options)
10
+ @config_paths = options.fetch(:config_paths)
11
+ @exec_on_hup = options.fetch(:exec_on_hup, false)
12
+ @fast_exit = options.fetch(:fast_exit, false)
13
+ @pidfile = options.fetch(:master_pidfile, nil)
14
+ end
15
+
16
+ # Public: Restore state from a serialized form.
17
+ def restore(data)
18
+ @config_paths = data[:config_paths]
19
+ @current_listener_pid = data[:current_listener_pid]
20
+ @exec_on_hup = data[:exec_on_hup]
21
+ @fast_exit = data[:fast_exit]
22
+ @last_good_listener_pid = data[:last_good_listener_pid]
23
+ @listeners_created = data[:listeners_created]
24
+ data[:listener_states].each do |lsh|
25
+ @listener_states[lsh[:pid]] = ListenerState.new.tap do |ls|
26
+ ls.master_socket = lsh[:master_socket] && Socket.for_fd(lsh[:master_socket])
27
+ ls.options = lsh[:options]
28
+ ls.pid = lsh[:pid]
29
+ ls.worker_pids = lsh[:worker_pids]
30
+ end
31
+ end
32
+ @paused = data[:paused]
33
+ @pidfile = data[:pidfile]
34
+ end
35
+
36
+ # Public: Return this state so that it can be serialized.
37
+ def to_h
38
+ {
39
+ config_paths: @config_paths,
40
+ current_listener_pid: @current_listener_pid,
41
+ exec_on_hup: @exec_on_hup,
42
+ fast_exit: @fast_exit,
43
+ last_good_listener_pid: @last_good_listener_pid,
44
+ listeners_created: @listeners_created,
45
+ listener_states: @listener_states.values.map { |ls|
46
+ {
47
+ master_socket: ls.master_socket&.to_i,
48
+ options: ls.options,
49
+ pid: ls.pid,
50
+ worker_pids: ls.worker_pids,
51
+ }
52
+ },
53
+ paused: @paused,
54
+ pidfile: @pidfile,
55
+ }
56
+ end
57
+
58
+ # Public: Return an array of open sockets or other file handles that should be forwarded to a new master.
59
+ def sockets
60
+ @listener_states.values.map { |l| l.master_socket }.compact
61
+ end
62
+
63
+ attr_reader :config_paths
64
+ attr_accessor :current_listener_pid
65
+ attr_reader :exec_on_hup
66
+ attr_reader :fast_exit
67
+ attr_accessor :last_good_listener_pid
68
+ attr_accessor :listeners_created
69
+ attr_reader :listener_states
70
+ attr_accessor :paused
71
+ attr_reader :pidfile
72
+ end
73
+ end
@@ -1,4 +1,4 @@
1
- require 'resqued/version'
1
+ require "resqued/version"
2
2
 
3
3
  module Resqued
4
4
  module ProclineVersion
@@ -6,7 +6,7 @@ module Resqued
6
6
  @version ||=
7
7
  begin
8
8
  # If we've built a custom version, this should show the custom version.
9
- Gem.loaded_specs['resqued'].version.to_s
9
+ Gem.loaded_specs["resqued"].version.to_s
10
10
  rescue Object
11
11
  # If this isn't a gem, fall back to the version in resqued/version.rb.
12
12
  Resqued::VERSION
@@ -1,9 +1,11 @@
1
- require 'fcntl'
2
- require 'kgio'
1
+ require "fcntl"
2
+ require "kgio"
3
3
 
4
4
  module Resqued
5
5
  module Sleepy
6
- # Public: Like sleep, but the sleep is interrupted if input is detected on one of the provided IO objects, or if `awake` is called (e.g. from a signal handler).
6
+ # Public: Like sleep, but the sleep is interrupted if input is
7
+ # detected on one of the provided IO objects, or if `awake` is
8
+ # called (e.g. from a signal handler).
7
9
  def yawn(duration, *inputs)
8
10
  if duration > 0
9
11
  inputs = [self_pipe[0]] + [inputs].flatten.compact
@@ -14,7 +16,7 @@ module Resqued
14
16
 
15
17
  # Public: Break out of `yawn`.
16
18
  def awake
17
- self_pipe[1].kgio_trywrite('.')
19
+ self_pipe[1].kgio_trywrite(".")
18
20
  end
19
21
 
20
22
  # Private.
@@ -1,5 +1,5 @@
1
- require 'resqued/config'
2
- require 'resqued/runtime_info'
1
+ require "resqued/config"
2
+ require "resqued/runtime_info"
3
3
 
4
4
  module Resqued
5
5
  module TestCase
@@ -17,7 +17,7 @@ module Resqued
17
17
  config = Resqued::Config.new(paths)
18
18
  config.before_fork(RuntimeInfo.new)
19
19
  config.build_workers
20
- config.after_fork(Resque::Worker.new('*'))
20
+ config.after_fork(Resque::Worker.new("*"))
21
21
  end
22
22
  end
23
23
 
@@ -1,3 +1,3 @@
1
1
  module Resqued
2
- VERSION = '0.8.4'
2
+ VERSION = '0.10.1'
3
3
  end
@@ -1,18 +1,28 @@
1
- require 'resque'
1
+ require "resque"
2
+ require "digest"
2
3
 
3
- require 'resqued/backoff'
4
- require 'resqued/logging'
4
+ require "resqued/backoff"
5
+ require "resqued/logging"
5
6
 
6
7
  module Resqued
7
8
  # Models a worker process.
8
9
  class Worker
9
10
  include Resqued::Logging
10
11
 
12
+ DEFAULT_WORKER_FACTORY = lambda { |queues|
13
+ resque_worker = Resque::Worker.new(*queues)
14
+ resque_worker.term_child = true if resque_worker.respond_to?("term_child=")
15
+ redis_client = Resque.redis.respond_to?(:_client) ? Resque.redis._client : Resque.redis.client
16
+ redis_client.reconnect
17
+ resque_worker
18
+ }
19
+
11
20
  def initialize(options)
12
21
  @queues = options.fetch(:queues)
13
22
  @config = options.fetch(:config)
14
23
  @interval = options[:interval]
15
24
  @backoff = Backoff.new
25
+ @worker_factory = options.fetch(:worker_factory, DEFAULT_WORKER_FACTORY)
16
26
  @pids = []
17
27
  end
18
28
 
@@ -34,12 +44,13 @@ module Resqued
34
44
 
35
45
  # Public: A string that compares if this worker is equivalent to a worker in another Resqued::Listener.
36
46
  def queue_key
37
- queues.sort.join(';')
47
+ Digest::SHA256.hexdigest(queues.sort.join(";"))
38
48
  end
39
49
 
40
50
  # Public: Claim this worker for another listener's worker.
41
51
  def wait_for(pid)
42
52
  raise "Already running #{@pid} (can't wait for #{pid})" if @pid
53
+
43
54
  @self_started = false
44
55
  @pids << pid
45
56
  @pid = pid
@@ -47,16 +58,17 @@ module Resqued
47
58
 
48
59
  # Public: The old worker process finished!
49
60
  def finished!(process_status)
50
- if process_status.nil? && ! @self_started
51
- log :debug, "(#{@pid}/#{@pids.inspect}/self_started=#{@self_started}/killed=#{@killed}) I am no longer blocked."
61
+ summary = "(#{@pid}/#{@pids.inspect}/self_started=#{@self_started}/killed=#{@killed})"
62
+ if process_status.nil? && !@self_started
63
+ log :debug, "#{summary} I am no longer blocked."
52
64
  @pid = nil
53
65
  @backoff.died unless @killed
54
- elsif ! process_status.nil? && @self_started
55
- log :debug, "(#{@pid}/#{@pids.inspect}/self_started=#{@self_started}/killed=#{@killed}) I exited: #{process_status}"
66
+ elsif !process_status.nil? && @self_started
67
+ log :debug, "#{summary} I exited: #{process_status}"
56
68
  @pid = nil
57
69
  @backoff.died unless @killed
58
70
  else
59
- log :debug, "(#{@pid}/#{@pids.inspect}/self_started=#{@self_started}/killed=#{@killed}) Reports of my death are highly exaggerated (#{process_status.inspect})"
71
+ log :debug, "#{summary} Reports of my death are highly exaggerated (#{process_status.inspect})"
60
72
  end
61
73
  end
62
74
 
@@ -68,6 +80,7 @@ module Resqued
68
80
  # Public: Start a job, if there's one waiting in one of my queues.
69
81
  def try_start
70
82
  return if @backoff.wait?
83
+
71
84
  @backoff.started
72
85
  @self_started = true
73
86
  @killed = false
@@ -77,12 +90,10 @@ module Resqued
77
90
  log "Forked worker #{@pid}"
78
91
  else
79
92
  # In case we get a signal before resque is ready for it.
80
- Resqued::Listener::ALL_SIGNALS.each { |signal| trap(signal, 'DEFAULT') }
93
+ Resqued::Listener::ALL_SIGNALS.each { |signal| trap(signal, "DEFAULT") }
81
94
  trap(:QUIT) { exit! 0 } # If we get a QUIT during boot, just spin back down.
82
95
  $0 = "STARTING RESQUE FOR #{queues.join(',')}"
83
- resque_worker = Resque::Worker.new(*queues)
84
- resque_worker.term_child = true if resque_worker.respond_to?('term_child=')
85
- Resque.redis.client.reconnect
96
+ resque_worker = @worker_factory.call(queues)
86
97
  @config.after_fork(resque_worker)
87
98
  resque_worker.work(@interval || 5)
88
99
  exit 0
@@ -1,3 +1,6 @@
1
- after_fork { raise 'boom' }
1
+ after_fork do
2
+ raise "boom"
3
+ end
4
+
2
5
  worker_pool 100
3
- queue 'test'
6
+ queue "test"
@@ -1,2 +1,5 @@
1
- before_fork { raise 'boom' }
1
+ before_fork do
2
+ raise "boom"
3
+ end
4
+
2
5
  worker "test"
@@ -1 +1,3 @@
1
- before_fork { Resque.redis = Redis.new(:host => 'localhost', :port => ENV['RESQUED_TEST_REDIS_PORT'].to_i) }
1
+ before_fork do
2
+ Resque.redis = Redis.new(host: "localhost", port: ENV["RESQUED_TEST_REDIS_PORT"].to_i)
3
+ end
@@ -1,61 +1,61 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
- require 'resqued/backoff'
3
+ require "resqued/backoff"
4
4
 
5
5
  describe Resqued::Backoff do
6
- let(:backoff) { described_class.new(:min => 0.5, :max => 64.0) }
6
+ let(:backoff) { described_class.new(min: 0.5, max: 64.0) }
7
7
 
8
- it 'can start on the first try' do
9
- expect(backoff.wait?).to be_false
8
+ it "can start on the first try" do
9
+ expect(backoff.wait?).to be_falsey
10
10
  end
11
11
 
12
- it 'has no waiting at first' do
12
+ it "has no waiting at first" do
13
13
  expect(backoff.how_long?).to be_nil
14
14
  end
15
15
 
16
- context 'after expected exits' do
16
+ context "after expected exits" do
17
17
  before { 3.times { backoff.started } }
18
- it { expect(backoff.wait?).to be_true }
18
+ it { expect(backoff.wait?).to be true }
19
19
  it { expect(backoff.how_long?).to be_close_to(0.5) }
20
20
  end
21
21
 
22
- context 'after one quick exit' do
23
- before { 1.times { backoff.started ; backoff.died } }
24
- it { expect(backoff.wait?).to be_true }
22
+ context "after one quick exit" do
23
+ before { 1.times { backoff.started; backoff.died } }
24
+ it { expect(backoff.wait?).to be true }
25
25
  it { expect(backoff.how_long?).to be_close_to(1.0) }
26
26
  end
27
27
 
28
- context 'after two quick starts' do
29
- before { 2.times { backoff.started ; backoff.died } }
30
- it { expect(backoff.wait?).to be_true }
28
+ context "after two quick starts" do
29
+ before { 2.times { backoff.started; backoff.died } }
30
+ it { expect(backoff.wait?).to be true }
31
31
  it { expect(backoff.how_long?).to be_close_to(2.0) }
32
32
  end
33
33
 
34
- context 'after five quick starts' do
35
- before { 6.times { backoff.started ; backoff.died } }
36
- it { expect(backoff.wait?).to be_true }
34
+ context "after five quick starts" do
35
+ before { 6.times { backoff.started; backoff.died } }
36
+ it { expect(backoff.wait?).to be true }
37
37
  it { expect(backoff.how_long?).to be_close_to(32.0) }
38
38
  end
39
39
 
40
- context 'after six quick starts' do
41
- before { 7.times { backoff.started ; backoff.died } }
42
- it { expect(backoff.wait?).to be_true }
40
+ context "after six quick starts" do
41
+ before { 7.times { backoff.started; backoff.died } }
42
+ it { expect(backoff.wait?).to be true }
43
43
  it { expect(backoff.how_long?).to be_close_to(64.0) }
44
44
  end
45
45
 
46
- context 'does not wait longer than 64s' do
47
- before { 8.times { backoff.started ; backoff.died } }
48
- it { expect(backoff.wait?).to be_true }
46
+ context "does not wait longer than 64s" do
47
+ before { 8.times { backoff.started; backoff.died } }
48
+ it { expect(backoff.wait?).to be true }
49
49
  it { expect(backoff.how_long?).to be_close_to(64.0) }
50
- it 'and resets after an expected exit' do
50
+ it "and resets after an expected exit" do
51
51
  backoff.started
52
52
  backoff.started
53
- expect(backoff.wait?).to be_true
53
+ expect(backoff.wait?).to be true
54
54
  expect(backoff.how_long?).to be_close_to(0.5)
55
55
  end
56
56
  end
57
57
 
58
- def be_close_to(x)
59
- be_within(0.005).of(x)
58
+ def be_close_to(number)
59
+ be_within(0.005).of(number)
60
60
  end
61
61
  end
@@ -1,12 +1,12 @@
1
- require 'spec_helper'
2
- require 'resqued/config/after_fork'
3
- require 'resqued/config/before_fork'
4
- require 'resqued/runtime_info'
1
+ require "spec_helper"
2
+ require "resqued/config/after_fork"
3
+ require "resqued/config/before_fork"
4
+ require "resqued/runtime_info"
5
5
 
6
6
  describe do
7
7
  before { evaluator.apply(config) }
8
8
 
9
- context 'after_fork' do
9
+ context "after_fork" do
10
10
  # Run the after_fork block.
11
11
  #
12
12
  # after_fork do |resque_worker|
@@ -26,13 +26,13 @@ describe do
26
26
  end
27
27
  END_CONFIG
28
28
 
29
- let(:evaluator) { Resqued::Config::AfterFork.new(:worker => worker) }
29
+ let(:evaluator) { Resqued::Config::AfterFork.new(worker: worker) }
30
30
  let(:worker) { FakeResqueWorker.new }
31
31
 
32
32
  it { expect(worker.token).to eq(:called) }
33
33
  end
34
34
 
35
- context 'before_fork' do
35
+ context "before_fork" do
36
36
  # Run the before_fork block.
37
37
  #
38
38
  # before_fork do
@@ -56,7 +56,7 @@ describe do
56
56
  end
57
57
  END_CONFIG
58
58
 
59
- let(:evaluator) { $before_fork_called = false ; Resqued::Config::BeforeFork.new(:resqued => resqued) }
59
+ let(:evaluator) { $before_fork_called = false; Resqued::Config::BeforeFork.new(resqued: resqued) }
60
60
  let(:resqued) { Resqued::RuntimeInfo.new }
61
61
 
62
62
  it { expect($before_fork_called).to eq(true) }
@@ -1,5 +1,5 @@
1
- require 'spec_helper'
2
- require 'resqued/config/worker'
1
+ require "spec_helper"
2
+ require "resqued/config/worker"
3
3
 
4
4
  describe Resqued::Config::Worker do
5
5
  # Create a bunch of Resqued::Worker objects from
@@ -15,7 +15,7 @@ describe Resqued::Config::Worker do
15
15
  #
16
16
  # ignore calls to any other top-level method.
17
17
 
18
- let(:evaluator) { described_class.new(:worker_class => FakeWorker) }
18
+ let(:evaluator) { described_class.new(worker_class: FakeWorker) }
19
19
  let(:result) { evaluator.apply(config) }
20
20
  module FakeWorker
21
21
  def self.new(options)
@@ -23,7 +23,7 @@ describe Resqued::Config::Worker do
23
23
  end
24
24
  end
25
25
 
26
- context 'individual' do
26
+ context "individual" do
27
27
  let(:config) { <<-END_CONFIG }
28
28
  before_fork { }
29
29
  after_fork { }
@@ -35,25 +35,38 @@ describe Resqued::Config::Worker do
35
35
  after_fork { } # So that we don't rely on `workers`'s result falling through.
36
36
  END_CONFIG
37
37
  it { expect(result.size).to eq(6) }
38
- it { expect(result[0]).to eq(:queues => ['a']) }
39
- it { expect(result[1]).to eq(:queues => ['a']) }
40
- it { expect(result[2]).to eq(:queues => ['b']) }
41
- it { expect(result[3]).to eq(:queues => ['c', 'd']) }
42
- it { expect(result[4]).to eq(:queues => ['d', 'c'], :interval => 3) }
43
- it { expect(result[5]).to eq(:queues => ['*']) }
38
+ it { expect(result[0]).to eq(queues: ["a"]) }
39
+ it { expect(result[1]).to eq(queues: ["a"]) }
40
+ it { expect(result[2]).to eq(queues: ["b"]) }
41
+ it { expect(result[3]).to eq(queues: ["c", "d"]) }
42
+ it { expect(result[4]).to eq(queues: ["d", "c"], interval: 3) }
43
+ it { expect(result[5]).to eq(queues: ["*"]) }
44
44
  end
45
45
 
46
- context 'concise pool' do
46
+ context "concise pool" do
47
47
  let(:config) { <<-END_CONFIG }
48
48
  worker_pool 2, 'a', 'b', 'c', :interval => 1
49
49
  END_CONFIG
50
- it { expect(result).to eq([
51
- { :queues => ['a', 'b', 'c'], :interval => 1 },
52
- { :queues => ['a', 'b', 'c'], :interval => 1 },
53
- ]) }
50
+ it do
51
+ expect(result).to eq([
52
+ { queues: ["a", "b", "c"], interval: 1 },
53
+ { queues: ["a", "b", "c"], interval: 1 },
54
+ ])
55
+ end
54
56
  end
55
57
 
56
- context 'pool (hash for concurrency)' do
58
+ context "small pool with percent" do
59
+ let(:config) { <<-END_CONFIG }
60
+ worker_pool 2
61
+ queue "a"
62
+ queue "b", :percent => 45
63
+ END_CONFIG
64
+ it { expect(result.size).to eq(2) }
65
+ it { expect(result[0]).to eq(queues: ["a", "b"]) }
66
+ it { expect(result[1]).to eq(queues: ["a"]) }
67
+ end
68
+
69
+ context "pool (hash for concurrency)" do
57
70
  let(:config) { <<-END_CONFIG }
58
71
  before_fork { }
59
72
  after_fork { }
@@ -64,15 +77,15 @@ describe Resqued::Config::Worker do
64
77
  after_fork { } # So that we don't rely on `worker_pool`'s result falling through.
65
78
  END_CONFIG
66
79
  it { expect(result.size).to eq(20) }
67
- it { expect(result[0]).to eq(:queues => ['a', 'b1', 'b2', 'c'], :interval => 1) }
68
- it { expect(result[3]).to eq(:queues => ['a', 'b1', 'b2', 'c'], :interval => 1) }
69
- it { expect(result[4]).to eq(:queues => ['b1', 'b2', 'c'], :interval => 1) }
70
- it { expect(result[9]).to eq(:queues => ['b1', 'b2', 'c'], :interval => 1) }
71
- it { expect(result[10]).to eq(:queues => ['c'], :interval => 1) }
72
- it { expect(result[19]).to eq(:queues => ['c'], :interval => 1) }
80
+ it { expect(result[0]).to eq(queues: ["a", "b1", "b2", "c"], interval: 1) }
81
+ it { expect(result[3]).to eq(queues: ["a", "b1", "b2", "c"], interval: 1) }
82
+ it { expect(result[4]).to eq(queues: ["b1", "b2", "c"], interval: 1) }
83
+ it { expect(result[9]).to eq(queues: ["b1", "b2", "c"], interval: 1) }
84
+ it { expect(result[10]).to eq(queues: ["c"], interval: 1) }
85
+ it { expect(result[19]).to eq(queues: ["c"], interval: 1) }
73
86
  end
74
87
 
75
- context 'pool, with implied queue' do
88
+ context "pool, with implied queue" do
76
89
  let(:config) { <<-END_CONFIG }
77
90
  before_fork { }
78
91
  after_fork { }
@@ -80,11 +93,11 @@ describe Resqued::Config::Worker do
80
93
  after_fork { } # So that we don't rely on `worker_pool`'s result falling through.
81
94
  END_CONFIG
82
95
  it { expect(result.size).to eq(20) }
83
- it { expect(result[0]).to eq(:queues => ['*']) }
84
- it { expect(result[19]).to eq(:queues => ['*']) }
96
+ it { expect(result[0]).to eq(queues: ["*"]) }
97
+ it { expect(result[19]).to eq(queues: ["*"]) }
85
98
  end
86
99
 
87
- context 'pool, with fewer queues than workers' do
100
+ context "pool, with fewer queues than workers" do
88
101
  let(:config) { <<-END_CONFIG }
89
102
  before_fork { }
90
103
  after_fork { }
@@ -93,13 +106,13 @@ describe Resqued::Config::Worker do
93
106
  after_fork { } # So that we don't rely on `worker_pool`'s result falling through.
94
107
  END_CONFIG
95
108
  it { expect(result.size).to eq(20) }
96
- it { expect(result[0]).to eq(:queues => ['a']) }
97
- it { expect(result[9]).to eq(:queues => ['a']) }
98
- it { expect(result[10]).to eq(:queues => ['*']) }
99
- it { expect(result[19]).to eq(:queues => ['*']) }
109
+ it { expect(result[0]).to eq(queues: ["a"]) }
110
+ it { expect(result[9]).to eq(queues: ["a"]) }
111
+ it { expect(result[10]).to eq(queues: ["*"]) }
112
+ it { expect(result[19]).to eq(queues: ["*"]) }
100
113
  end
101
114
 
102
- context 'pool, with more queues than workers' do
115
+ context "pool, with more queues than workers" do
103
116
  let(:config) { <<-END_CONFIG }
104
117
  before_fork { }
105
118
  after_fork { }
@@ -110,41 +123,64 @@ describe Resqued::Config::Worker do
110
123
  it { expect(result.size).to eq(20) }
111
124
  end
112
125
 
113
- context 'pool, with shuffled queues' do
126
+ context "pool, with shuffled queues" do
114
127
  let(:config) { <<-END_CONFIG }
115
128
  worker_pool 20, :shuffle_queues => true
116
129
  queue 'a', :count => 10
117
130
  queue 'b', :count => 15
118
131
  END_CONFIG
119
132
  it { expect(result.size).to eq(20) }
120
- it { (0..9).each { |i| expect(result[i][:queues].sort).to eq(['a', 'b']) } }
121
- it { (10..14).each { |i| expect(result[i][:queues]).to eq(['b']) } }
122
- it { (15..19).each { |i| expect(result[i][:queues]).to eq(['*']) } }
133
+ it { (0..9).each { |i| expect(result[i][:queues].sort).to eq(["a", "b"]) } }
134
+ it { (10..14).each { |i| expect(result[i][:queues]).to eq(["b"]) } }
135
+ it { (15..19).each { |i| expect(result[i][:queues]).to eq(["*"]) } }
123
136
  it { result.each { |x| expect(x).not_to have_key(:shuffle_queues) } }
124
137
  it do
125
138
  shuffled_queues = result.take(10).map { |x| x[:queues] }
126
- expect(shuffled_queues.sort.uniq).to eq([ ['a','b'], ['b','a'] ]) # Some of the queues should be shuffled
139
+ expect(shuffled_queues.sort.uniq).to eq([["a", "b"], ["b", "a"]]) # Some of the queues should be shuffled
127
140
  end
128
141
  end
129
142
 
130
- context 'multiple worker configs' do
143
+ context "multiple worker configs" do
131
144
  let(:config) { <<-END_CONFIG }
132
145
  worker 'one'
133
146
  worker 'two'
134
147
  worker_pool 2
135
148
  END_CONFIG
136
149
  it { expect(result.size).to eq(4) }
137
- it { expect(result[0]).to eq(:queues => ['one']) }
138
- it { expect(result[1]).to eq(:queues => ['two']) }
139
- it { expect(result[2]).to eq(:queues => ['*']) }
140
- it { expect(result[3]).to eq(:queues => ['*']) }
150
+ it { expect(result[0]).to eq(queues: ["one"]) }
151
+ it { expect(result[1]).to eq(queues: ["two"]) }
152
+ it { expect(result[2]).to eq(queues: ["*"]) }
153
+ it { expect(result[3]).to eq(queues: ["*"]) }
154
+ end
155
+
156
+ context "worker factory" do
157
+ let(:config) { <<-END_CONFIG }
158
+ worker_factory { |queues| queues }
159
+ worker 'a'
160
+ END_CONFIG
161
+
162
+ it { expect(result.size).to eq(1) }
163
+ it { expect(result[0].reject { |k, _| k == :worker_factory }).to eq(queues: ["a"]) }
164
+ it { expect(result[0][:worker_factory].call(result[0][:queues])).to eq(["a"]) }
165
+ end
166
+
167
+ context "worker factory with pool" do
168
+ let(:config) { <<-END_CONFIG }
169
+ worker_factory { |queues| queues }
170
+ worker_pool 1
171
+ queue 'a'
172
+ END_CONFIG
173
+
174
+ it { expect(result.size).to eq(1) }
175
+ it { expect(result[0].reject { |k, _| k == :worker_factory }).to eq(queues: ["a"]) }
176
+ it { expect(result[0][:worker_factory].call(result[0][:queues])).to eq(["a"]) }
141
177
  end
142
178
 
143
- context 'with default options' do
144
- let(:evaluator) { described_class.new(:worker_class => FakeWorker, :config => 'something') }
179
+ context "with default options" do
180
+ let(:evaluator) { described_class.new(worker_class: FakeWorker, config: "something") }
145
181
  let(:config) { <<-END_CONFIG }
146
182
  worker 'a', :interval => 1
147
183
  END_CONFIG
148
- it { expect(result[0]).to eq(:queues => ['a'], :interval => 1, :config => 'something') }
184
+ it { expect(result[0]).to eq(queues: ["a"], interval: 1, config: "something") }
149
185
  end
150
186
  end