attentive_sidekiq 0.2.1 → 0.3.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: 1a5dd7d7255704b9f2a4c0a17a494457f9827aac
4
- data.tar.gz: 989e2e842e2de465df0c23235861c66da5eaa8eb
3
+ metadata.gz: 710aa8d08d27aece645bef61d22be38bdf5424f5
4
+ data.tar.gz: e8dde883933212b7ea5659749d12cb810005bc2d
5
5
  SHA512:
6
- metadata.gz: decd8b0dd325a36d57d74ed5635203b6ddc5da90ea6f3faa6dafa222ede9e6b6c2d1332802b4b9d904c5cdb1586d86919989660fe9f2b5a9a90086859ed8fdab
7
- data.tar.gz: ef514362d5011d880cae7ab7ee70eda9f39738719e022c542549247033768f38e19faa354cb1f904528a60390f27b6384dff71936065c9aae854cafc553ae683
6
+ metadata.gz: fd6587c4312f1e2cf96cf2bc106f509c3464f871fcb8acd08faf031ad1dd207d85ddac21d9e5eacde83dcb7e8a96f162238801d497d88bab6b284977e8775e27
7
+ data.tar.gz: 629fb700fca7a68df8054624a648319db57feb9a0f154a4a7b38a6c5a2b87df3f09888f2e13c8474455d91ffdb2956c9935741ea54288968d9267a71821cbeff
@@ -1,25 +1,23 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- attentive_sidekiq (0.1.0)
4
+ attentive_sidekiq (0.3.0)
5
5
  activesupport
6
6
  concurrent-ruby (~> 1.0)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- activesupport (4.2.5)
11
+ activesupport (5.0.0.1)
12
+ concurrent-ruby (~> 1.0, >= 1.0.2)
12
13
  i18n (~> 0.7)
13
- json (~> 1.7, >= 1.7.7)
14
14
  minitest (~> 5.1)
15
- thread_safe (~> 0.3, >= 0.3.4)
16
15
  tzinfo (~> 1.1)
17
16
  byebug (9.0.6)
18
17
  coderay (1.1.1)
19
18
  concurrent-ruby (1.0.2)
20
19
  connection_pool (2.2.1)
21
20
  i18n (0.7.0)
22
- json (1.8.3)
23
21
  method_source (0.8.2)
24
22
  minitest (5.9.1)
25
23
  minitest-stub_any_instance (1.0.1)
data/README.md CHANGED
@@ -1,24 +1,21 @@
1
- # Attentive Sidekiq
1
+ Attentive Sidekiq
2
+ ===========================
2
3
 
3
4
  [![Gem Version](https://badge.fury.io/rb/attentive_sidekiq.svg)](https://badge.fury.io/rb/attentive_sidekiq)
4
5
  [![Code Climate](https://codeclimate.com/github/twonegatives/attentive_sidekiq/badges/gpa.svg)](https://codeclimate.com/github/twonegatives/attentive_sidekiq)
5
6
  [![CircleCI](https://circleci.com/gh/twonegatives/attentive_sidekiq.svg?style=shield)](https://circleci.com/gh/twonegatives/attentive_sidekiq)
6
7
 
8
+ Be aware of suddenly disappeared sidekiq jobs!
7
9
 
8
- ### Motivation
9
- Bad things happen sometimes. Sidekiq process being killed in the middle of job processing may lead to job losage. In other words, that job will never be returned to the queue.
10
- This case was proved by [github issues](https://github.com/mperham/sidekiq/issues/1831), [stackoverflow questions](http://stackoverflow.com/questions/35555000/current-sidekiq-job-lost-when-deploying-to-heroku) and (sadly) personal experience, and means that you are not safe from losing critical user data.
11
- Sidekiq's author, Mike Perham, suggests purchasing Sidekiq Pro which uses another fetch mechanism. However, it [is reported](https://github.com/mperham/sidekiq/issues/2531) to still cause the same issue.
10
+ ![shortsummary](https://cloud.githubusercontent.com/assets/1937799/20489411/fe726e82-b023-11e6-9528-7df519fec7dd.gif)
12
11
 
13
- ### About
14
- Attentive Sidekiq is a sidekiq plugin which makes one more step to guard your jobs from being lost (well, at least to be notified of this).
15
- It saves info about started jobs into additional redis hash and keeps them there till jobs are finished.
16
- In case there appears a job being started but not finished and not being processing at the moment, you will know something bad happened.
12
+ ### About
13
+ The case of disappearing sidekiq jobs was proved by [github issues](https://github.com/mperham/sidekiq/issues/1831), [stackoverflow questions](http://stackoverflow.com/questions/35555000/current-sidekiq-job-lost-when-deploying-to-heroku) and (sadly) personal experience. Attentive Sidekiq was made to protect your jobs and critical data from silent disappearing. In case there appears a job being started but not finished and not being processing at the moment, you will know this.
17
14
 
18
15
  ### Usage
19
16
  Attentive Sidekiq provides you with a couple of useful API methods.
20
17
 
21
- To get a hash containing all information about jobs marked as lost:
18
+ To get a hash containing all information about jobs marked as disappeared:
22
19
  ```ruby
23
20
  AttentiveSidekiq::Disappeared.jobs
24
21
  ```
@@ -43,7 +40,7 @@ You may also watch info about disappeared jobs in a web UI.
43
40
  Simply make sure you have Sidekiq UI enabled, then head right to the Disappeared Jobs tab in the navbar.
44
41
  The Web UI uses the API exclusively: anything you can do in the UI can be scripted with the API.
45
42
 
46
- ![Web UI](web.png)
43
+ ![webui](https://cloud.githubusercontent.com/assets/1937799/20490807/a01216d0-b028-11e6-96b7-c23fd67bdf89.png)
47
44
 
48
45
  ### Pre-requirements and notes
49
46
 
@@ -73,6 +70,24 @@ end
73
70
 
74
71
  After that you can use your jobs as usual.
75
72
 
73
+ ### Configuration
74
+
75
+ Specify desired configuration inside of `sidekiq.yml` file:
76
+
77
+ ```YML
78
+ attentive:
79
+ # Time in seconds between checks for disappeared jobs
80
+ :execution_interval: 300 # default: 600
81
+ # Time limit in seconds to perform disappeared jobs check
82
+ :timeout_interval: 25 # default: 60
83
+ ```
84
+
85
+ By default, Attentive Sidekiq uses `Sidekiq.logger` to log its work. You may change it in your initializer:
86
+
87
+ ```ruby
88
+ AttentiveSidekiq.logger = Logger.new("log/attentive_sidekiq.log")
89
+ ```
90
+
76
91
  ### Suggestions? Bugs?
77
92
 
78
93
  If you've got a question, feature suggestion or found a bug please add an [issue on GitHub](https://github.com/twonegatives/attentive_sidekiq/issues) or fork the project and send a pull request.
Binary file
@@ -2,7 +2,6 @@ require 'set'
2
2
  require 'active_support/inflector'
3
3
  require 'active_support/core_ext/hash'
4
4
  require 'concurrent'
5
- require 'attentive_sidekiq/middleware'
6
5
  require 'attentive_sidekiq/api'
7
6
  require 'attentive_sidekiq/middleware/server/attentionist'
8
7
  require 'attentive_sidekiq/middleware/client/attentionist'
@@ -12,11 +11,36 @@ require 'sidekiq/web' unless defined?(Sidekiq::Web)
12
11
  require 'attentive_sidekiq/web'
13
12
 
14
13
  module AttentiveSidekiq
14
+ DEFAULTS = {
15
+ timeout_interval: 60,
16
+ execution_interval: 600,
17
+ }
18
+
19
+ REDIS_SUSPICIOUS_KEY = "attentive_observed_hash"
20
+ REDIS_DISAPPEARED_KEY = "attentive_disappeared_hash"
21
+
15
22
  class << self
16
- attr_writer :logger
23
+ attr_writer :timeout_interval, :execution_interval, :logger
24
+
25
+ def timeout_interval
26
+ return @execution_timeout if @execution_timeout
27
+ @timeout_interval = options[:timeout_interval] || DEFAULTS[:timeout_interval]
28
+ end
29
+
30
+ def execution_interval
31
+ return @execution_interval if @execution_interval
32
+ @execution_interval = options[:execution_interval] || DEFAULTS[:execution_interval]
33
+ end
17
34
 
18
35
  def logger
19
36
  @logger ||= Sidekiq.logger
20
37
  end
38
+
39
+ def options
40
+ Sidekiq.options["attentive"] || {}
41
+ end
42
+
21
43
  end
22
44
  end
45
+
46
+ AttentiveSidekiq::Manager.instance.start! if Sidekiq.server?
@@ -20,17 +20,10 @@ module AttentiveSidekiq
20
20
  def remove jid
21
21
  Sidekiq.redis{|conn| conn.hdel(hash_name, jid)}
22
22
  end
23
-
24
- private
25
-
26
- def hash_name
27
- self.const_get(:HASH_NAME)
28
- end
29
23
  end
30
24
  end
31
25
 
32
26
  class Disappeared < RedisBasedHash
33
- HASH_NAME = AttentiveSidekiq::Middleware::REDIS_DISAPPEARED_KEY
34
27
  STATUS_DETECTED = 'detected'
35
28
  STATUS_REQUEUED = 'requeued'
36
29
 
@@ -47,11 +40,19 @@ module AttentiveSidekiq
47
40
  record['class'].constantize.perform_async(*record['args'])
48
41
  base_add(record.merge('status' => STATUS_REQUEUED))
49
42
  end
43
+
44
+ def hash_name
45
+ AttentiveSidekiq::REDIS_DISAPPEARED_KEY
46
+ end
50
47
  end
51
48
  end
52
49
 
53
50
  class Suspicious < RedisBasedHash
54
- HASH_NAME = AttentiveSidekiq::Middleware::REDIS_SUSPICIOUS_KEY
51
+ class << self
52
+ def hash_name
53
+ AttentiveSidekiq::REDIS_SUSPICIOUS_KEY
54
+ end
55
+ end
55
56
  end
56
57
 
57
58
  class Active
@@ -29,12 +29,11 @@ module AttentiveSidekiq
29
29
  private
30
30
 
31
31
  def options
32
- timeout = 1*60
33
- interval = 10*60
34
- { execution_interval: interval, timeout_interval: timeout }
32
+ {
33
+ execution_interval: AttentiveSidekiq.execution_interval,
34
+ timeout_interval: AttentiveSidekiq.timeout_interval
35
+ }
35
36
  end
36
37
 
37
38
  end
38
39
  end
39
-
40
- AttentiveSidekiq::Manager.instance.start! if Sidekiq.server?
@@ -1,3 +1,3 @@
1
1
  module AttentiveSidekiq
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -35,11 +35,11 @@ class ManagerTest < Minitest::Test
35
35
  end
36
36
 
37
37
  def suspicious_now
38
- Sidekiq.redis{|conn| conn.hvals(AttentiveSidekiq::Middleware::REDIS_SUSPICIOUS_KEY)}.map{|i| JSON.parse(i)}
38
+ Sidekiq.redis{|conn| conn.hvals(AttentiveSidekiq::REDIS_SUSPICIOUS_KEY)}.map{|i| JSON.parse(i)}
39
39
  end
40
40
 
41
41
  def disappeared_now
42
- from_redis = Sidekiq.redis{|conn| conn.hvals(AttentiveSidekiq::Middleware::REDIS_DISAPPEARED_KEY)}
42
+ from_redis = Sidekiq.redis{|conn| conn.hvals(AttentiveSidekiq::REDIS_DISAPPEARED_KEY)}
43
43
  from_redis.map{|i| JSON.parse(i).except('noticed_at', 'status')}
44
44
  end
45
45
  end
@@ -78,21 +78,21 @@ class ServerMiddlewareTest < Minitest::Test
78
78
  assert_equal 0, DefaultQueue.instance.size
79
79
  HardWorker.perform_async(1)
80
80
  assert_equal 1, DefaultQueue.instance.size
81
- assert_equal 0, Sidekiq.redis{|conn| conn.hvals(AttentiveSidekiq::Middleware::REDIS_SUSPICIOUS_KEY)}.size
81
+ assert_equal 0, Sidekiq.redis{|conn| conn.hvals(AttentiveSidekiq::REDIS_SUSPICIOUS_KEY)}.size
82
82
  end
83
83
 
84
84
  it "marks job as suspicious as soon as it is started" do
85
- assert_equal 0, Sidekiq.redis{|conn| conn.hvals(AttentiveSidekiq::Middleware::REDIS_SUSPICIOUS_KEY)}.size
85
+ assert_equal 0, Sidekiq.redis{|conn| conn.hvals(AttentiveSidekiq::REDIS_SUSPICIOUS_KEY)}.size
86
86
  HardWorker.perform_async(2, 100_000)
87
87
  Thread.new{
88
88
  SidekiqEmulator.instance.process_jobs
89
89
  }
90
90
  sleep(1) # TODO: refactor this somehow
91
- assert_equal 1, Sidekiq.redis{|conn| conn.hvals(AttentiveSidekiq::Middleware::REDIS_SUSPICIOUS_KEY)}.size
91
+ assert_equal 1, Sidekiq.redis{|conn| conn.hvals(AttentiveSidekiq::REDIS_SUSPICIOUS_KEY)}.size
92
92
  end
93
93
 
94
94
  it "removes suspicious mark as soon as job is finished succesfully" do
95
- assert_equal 0, Sidekiq.redis{|conn| conn.hvals(AttentiveSidekiq::Middleware::REDIS_SUSPICIOUS_KEY)}.size
95
+ assert_equal 0, Sidekiq.redis{|conn| conn.hvals(AttentiveSidekiq::REDIS_SUSPICIOUS_KEY)}.size
96
96
  HardWorker.perform_async(2, 1)
97
97
  Thread.new{
98
98
  @mutex.synchronize{
@@ -101,11 +101,11 @@ class ServerMiddlewareTest < Minitest::Test
101
101
  }
102
102
  }
103
103
  @mutex.synchronize{ @stopper.wait(@mutex) }
104
- assert_equal 0, Sidekiq.redis{|conn| conn.hvals(AttentiveSidekiq::Middleware::REDIS_SUSPICIOUS_KEY)}.size
104
+ assert_equal 0, Sidekiq.redis{|conn| conn.hvals(AttentiveSidekiq::REDIS_SUSPICIOUS_KEY)}.size
105
105
  end
106
106
 
107
107
  it "removes suspicious mark as soon as job failed" do
108
- assert_equal 0, Sidekiq.redis{|conn| conn.hvals(AttentiveSidekiq::Middleware::REDIS_SUSPICIOUS_KEY)}.size
108
+ assert_equal 0, Sidekiq.redis{|conn| conn.hvals(AttentiveSidekiq::REDIS_SUSPICIOUS_KEY)}.size
109
109
  HardWorker.perform_async(2, -1)
110
110
  Thread.new{
111
111
  @mutex.synchronize{
@@ -114,7 +114,7 @@ class ServerMiddlewareTest < Minitest::Test
114
114
  }
115
115
  }
116
116
  @mutex.synchronize{ @stopper.wait(@mutex) }
117
- assert_equal 0, Sidekiq.redis{|conn| conn.hvals(AttentiveSidekiq::Middleware::REDIS_SUSPICIOUS_KEY)}.size
117
+ assert_equal 0, Sidekiq.redis{|conn| conn.hvals(AttentiveSidekiq::REDIS_SUSPICIOUS_KEY)}.size
118
118
  end
119
119
  end
120
120
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attentive_sidekiq
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - twonegatives
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-20 00:00:00.000000000 Z
11
+ date: 2016-11-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sidekiq
@@ -164,10 +164,10 @@ files:
164
164
  - Rakefile
165
165
  - attentive_sidekiq.gemspec
166
166
  - circle.yml
167
+ - dump.rdb
167
168
  - lib/attentive_sidekiq.rb
168
169
  - lib/attentive_sidekiq/api.rb
169
170
  - lib/attentive_sidekiq/manager.rb
170
- - lib/attentive_sidekiq/middleware.rb
171
171
  - lib/attentive_sidekiq/middleware/client/attentionist.rb
172
172
  - lib/attentive_sidekiq/middleware/server/attentionist.rb
173
173
  - lib/attentive_sidekiq/updater_observer.rb
@@ -181,7 +181,6 @@ files:
181
181
  - test/server_middleware_test.rb
182
182
  - test/test_helper.rb
183
183
  - test/web_test.rb
184
- - web.png
185
184
  homepage: http://rubygems.org/gems/attentive_sidekiq
186
185
  licenses:
187
186
  - MIT
@@ -202,7 +201,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
202
201
  version: '0'
203
202
  requirements: []
204
203
  rubyforge_project:
205
- rubygems_version: 2.2.2
204
+ rubygems_version: 2.4.5
206
205
  signing_key:
207
206
  specification_version: 4
208
207
  summary: Make your sidekiq to be attentive to lost jobs
@@ -1,6 +0,0 @@
1
- module AttentiveSidekiq
2
- module Middleware
3
- REDIS_SUSPICIOUS_KEY = "attentive_observed_hash"
4
- REDIS_DISAPPEARED_KEY = "attentive_disappeared_hash"
5
- end
6
- end
data/web.png DELETED
Binary file