resqutils 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 63c56aed110c280ee955278e9d007f242482e15e
4
- data.tar.gz: 07eac3dc61ff36df991829d3002d805da88bd3d3
3
+ metadata.gz: 2663293b0ffb13621afe5b4d29b2a98a0505452a
4
+ data.tar.gz: 0cdd0723fab6b23d274c5f40e62181d1e1d9fc8a
5
5
  SHA512:
6
- metadata.gz: 91fc61241a2cd1c0b623f9473fab38ecfcc19f1d7b83c92a1c5c91f72e62c8378ce614950e530f7b535987dec8f3029f62cef0c1e573d139f6d3e8dc885481c2
7
- data.tar.gz: 2f5f870492b27271bd29ebc34e4b9d6f24c0117dcf443a479175ca545a514cb881352168e12095a807ce54670f8af685a6388bca85cdf18bb07c6d86fa7b90d7
6
+ metadata.gz: 4db81ced533e45a6892a8940f9b11f6c4b0b4933fbec2117bec8b302230f9ce79a670d775dc8982d634223cb740347f412a6520b8f5f70a68de662ed1c208dbc
7
+ data.tar.gz: c502717b9ff99592aca62f89df365c27c7689e1b2e81eac5fd976d1a66a6c164d110584e3e013b8f49224d7483b6290cc2d9782102bc08effe23b26c2a8ee549
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.0
4
+ - 2.2.0
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- resqutils (1.0.0)
4
+ resqutils (1.1.0)
5
5
  resque
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -33,17 +33,21 @@ failed handling (which is hopefully to restart your jobs).
33
33
  You need a means of identifying these workers, and then killing them.
34
34
 
35
35
  ```ruby
36
- Resqutils::StaleWorkers.new.each do |worker|
37
- # this worker is still considered running but has started over an hour ago
38
- Resque.enqueue(WorkerKillerJob,worker.id)
39
- end
36
+ Resqutils::StaleWorkersKiller.kill_stale_workers
40
37
  ```
41
38
 
42
- `Resqutils::StaleWorkers`'s default of an hour can be overridden either in the constructor or by setting the
43
- `RESQUTILS_SECONDS_TO_BE_CONSIDERED_STALE` environment variable.
39
+ This will queue a `WorkerKillerJob` for each stale worker. This uses `Resqutils::StaleWorkers` under the covers to identify
40
+ which are stale. You can pass it in to `StaleWorkersKiller`'s constructor, or configure it using the environment. By
41
+ default, a worker running for more than an hour is considered stale.
42
+
43
+ Setting the `RESQUTILS_SECONDS_TO_BE_CONSIDERED_STALE` environment variable, you can override that.
44
+
45
+ The queue that `WorkerKillerJob` will queue to is `worker_killer_job` by default, but can be changed by setting the `RESQUTILS_WORKER_KILLER_JOB_QUEUE` environment variable.
46
+
47
+ `Resqutils::StaleWorkersKiller` is also itself a resque job, so you can use this class directly in your resque-scheduler
48
+ implementation to kill stale jobs on a schedule.
44
49
 
45
- The queue that `WorkerKillerJob` will queue to is `worker_killer_job` by default, but can either be set during the `enqueue`
46
- call or by setting the `RESQUTILS_WORKER_KILLER_JOB_QUEUE` environment variable.
50
+ You can, of course, use these building blocks on your own for other purposes.
47
51
 
48
52
  ## Spec Helpers
49
53
 
data/lib/resqutils.rb CHANGED
@@ -4,4 +4,5 @@ end
4
4
  require 'resqutils/do_not_auto_retry'
5
5
  require 'resqutils/worker_killer_job'
6
6
  require 'resqutils/stale_workers'
7
+ require 'resqutils/stale_workers_killer'
7
8
  require 'resqutils/version'
@@ -0,0 +1,18 @@
1
+ module Resqutils
2
+ # Vends stale workers that have been running "too long"
3
+ class StaleWorkersKiller
4
+
5
+ def self.perform
6
+ self.new.kill_stale_workers
7
+ end
8
+
9
+ def initialize(stale_workers: nil)
10
+ @stale_workers = stale_workers || Resqutils::StaleWorkers.new
11
+ end
12
+ def kill_stale_workers
13
+ @stale_workers.each do |worker|
14
+ Resque.enqueue(Resqutils::WorkerKillerJob,worker.id)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,3 +1,3 @@
1
1
  module Resqutils
2
- VERSION='1.0.0'
2
+ VERSION='1.1.0'
3
3
  end
@@ -10,7 +10,7 @@ module Resqutils
10
10
  end
11
11
  end
12
12
  def self.perform(worker_id)
13
- Resque.workers.detect { |_| _.id == worker_id }.unregister_worker
13
+ Resque.workers.select { |_| _.id == worker_id }.each(&:unregister_worker)
14
14
  end
15
15
  end
16
16
  end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+ require 'support/worker_helper'
3
+
4
+ describe Resqutils::StaleWorkersKiller do
5
+ include WorkerHelper
6
+ let(:stale_workers) {
7
+ [
8
+ worker,
9
+ worker,
10
+ worker,
11
+ ]
12
+ }
13
+ before do
14
+ allow(Resque).to receive(:enqueue)
15
+ end
16
+ describe "kill_stale_workers" do
17
+ before do
18
+
19
+ described_class.new(stale_workers: stale_workers).kill_stale_workers
20
+ end
21
+ it "queues a job for all stale workers" do
22
+ stale_workers.each do |worker|
23
+ expect(Resque).to have_received(:enqueue).with(Resqutils::WorkerKillerJob,worker.id)
24
+ end
25
+ end
26
+ end
27
+ describe "::perform" do
28
+ before do
29
+ allow(Resqutils::StaleWorkers).to receive(:new).and_return(stale_workers)
30
+ described_class.perform
31
+ end
32
+ it "queues a job for all stale workers" do
33
+ stale_workers.each do |worker|
34
+ expect(Resque).to have_received(:enqueue).with(Resqutils::WorkerKillerJob,worker.id)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,6 +1,8 @@
1
1
  require 'spec_helper'
2
+ require 'support/worker_helper'
2
3
 
3
4
  describe Resqutils::StaleWorkers do
5
+ include WorkerHelper
4
6
  describe "each" do
5
7
  let(:workers) {
6
8
  [
@@ -139,10 +141,4 @@ describe Resqutils::StaleWorkers do
139
141
  end
140
142
  end
141
143
  end
142
-
143
- def worker(run_at = Time.now)
144
- double("resque worker", id: SecureRandom.uuid, job: { "queue" => "whatever",
145
- "run_at" => run_at.to_s,
146
- "payload" => { "class" => "Foo", "args" => [] } })
147
- end
148
144
  end
@@ -0,0 +1,7 @@
1
+ module WorkerHelper
2
+ def worker(run_at = Time.now)
3
+ double("resque worker", id: SecureRandom.uuid, job: { "queue" => "whatever",
4
+ "run_at" => run_at.to_s,
5
+ "payload" => { "class" => "Foo", "args" => [] } })
6
+ end
7
+ end
@@ -23,37 +23,48 @@ describe Resqutils::WorkerKillerJob do
23
23
  end
24
24
  end
25
25
  describe "::perform" do
26
- let(:workers) {
27
- [
28
- double(id: worker_id),
29
- double(id: worker_id),
30
- double(id: worker_id),
31
- double(id: worker_id),
32
- double(id: worker_id),
33
- double(id: worker_id),
34
- ]
35
- }
36
-
37
- let(:worker_to_kill) { workers[2] }
26
+ context "worker to kill exists" do
27
+ let(:workers) {
28
+ [
29
+ double(id: worker_id),
30
+ double(id: worker_id),
31
+ double(id: worker_id),
32
+ double(id: worker_id),
33
+ double(id: worker_id),
34
+ double(id: worker_id),
35
+ ]
36
+ }
38
37
 
39
- before do
40
- allow(Resque).to receive(:workers).and_return(workers)
41
- workers.each do |worker|
42
- allow(worker).to receive(:unregister_worker)
38
+ let(:worker_to_kill) { workers[2] }
39
+
40
+ before do
41
+ allow(Resque).to receive(:workers).and_return(workers)
42
+ workers.each do |worker|
43
+ allow(worker).to receive(:unregister_worker)
44
+ end
45
+ described_class.perform(worker_to_kill.id)
43
46
  end
44
- described_class.perform(worker_to_kill.id)
45
- end
46
47
 
47
- it "unregisters the worker we want to kill" do
48
- expect(worker_to_kill).to have_received(:unregister_worker)
49
- end
48
+ it "unregisters the worker we want to kill" do
49
+ expect(worker_to_kill).to have_received(:unregister_worker)
50
+ end
50
51
 
51
- it "doesn't touch the other workers" do
52
- workers.reject { |_| _ == worker_to_kill }.each do |worker|
53
- expect(worker).not_to have_received(:unregister_worker)
52
+ it "doesn't touch the other workers" do
53
+ workers.reject { |_| _ == worker_to_kill }.each do |worker|
54
+ expect(worker).not_to have_received(:unregister_worker)
55
+ end
56
+ end
57
+ end
58
+ context "worker to doesn't exist" do
59
+ before do
60
+ allow(Resque).to receive(:workers).and_return([])
61
+ end
62
+ it "doesn't blow up" do
63
+ expect {
64
+ described_class.perform(worker_id)
65
+ }.not_to raise_error
54
66
  end
55
67
  end
56
-
57
68
  end
58
69
 
59
70
  def worker_id
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resqutils
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stitch Fix Engineering
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-04 00:00:00.000000000 Z
11
+ date: 2015-02-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: resque
@@ -62,6 +62,7 @@ files:
62
62
  - ".gitignore"
63
63
  - ".ruby-gemset"
64
64
  - ".ruby-version"
65
+ - ".travis.yml"
65
66
  - Gemfile
66
67
  - Gemfile.lock
67
68
  - LICENSE.txt
@@ -73,12 +74,15 @@ files:
73
74
  - lib/resqutils/spec/resque_helpers.rb
74
75
  - lib/resqutils/spec/resque_matchers.rb
75
76
  - lib/resqutils/stale_workers.rb
77
+ - lib/resqutils/stale_workers_killer.rb
76
78
  - lib/resqutils/version.rb
77
79
  - lib/resqutils/worker_killer_job.rb
78
80
  - lib/resqutils/worker_task.rb
79
81
  - resqutils.gemspec
80
82
  - spec/spec_helper.rb
83
+ - spec/stale_workers_killer_spec.rb
81
84
  - spec/stale_workers_spec.rb
85
+ - spec/support/worker_helper.rb
82
86
  - spec/worker_killer_job_spec.rb
83
87
  homepage: http://tech.stitchfix.com
84
88
  licenses: []
@@ -105,5 +109,7 @@ specification_version: 4
105
109
  summary: Utilities for using Resque in a Rails app
106
110
  test_files:
107
111
  - spec/spec_helper.rb
112
+ - spec/stale_workers_killer_spec.rb
108
113
  - spec/stale_workers_spec.rb
114
+ - spec/support/worker_helper.rb
109
115
  - spec/worker_killer_job_spec.rb