sidekiq 3.2.1 → 3.2.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sidekiq might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 39626a2f12ce1c55fc3b6aec763a780fbbf3afe3
4
- data.tar.gz: d4edda55a00c8ee2fa5f67a102b71b3ee24cac18
3
+ metadata.gz: ac4be785d484b8190a4aeb09fc93d21f4897f2f1
4
+ data.tar.gz: 9955d71f3356939e2cc06f7287f66d850b18604c
5
5
  SHA512:
6
- metadata.gz: f4ca3aea1d5c28672337e784d9f34531f8d495f210e6a3f6c6aef56a34a91546f4bc77e8d89fedf655514b18bafff9209a3e0cc959a533ebc3c696f78a46c132
7
- data.tar.gz: b64813b493d5672027cdeeac9ff981d1aa6f2a2faab92a08b6e08a318205e1ec857c9abb500f8ce3a9b8908378988e10de147a8a43402f10071af5b0c528509b
6
+ metadata.gz: ba6263b604d50445ad7582a49870daf4af2105570d0d43fe6702128903bdda651c640435eff1d4f61fdeb828193ed91fc6552b536f87fc8cee3d4b313b7c13f9
7
+ data.tar.gz: 260002fc92ba5a50aa910402f388ca1f77f2c21aab076fcd59f8e9d04c68e48cbd2b2889f89ef1caee745e9a585af86f1ea9caa65c46af68983d23f66ec0e55c
@@ -2,7 +2,6 @@ language: ruby
2
2
  services:
3
3
  - redis-server
4
4
  rvm:
5
- - 1.9.3
6
5
  - jruby-19mode
7
6
  - rbx-2
8
7
  - 2.0.0
data/Changes.md CHANGED
@@ -1,3 +1,13 @@
1
+ 3.2.2
2
+ -----------
3
+
4
+ - Fix issue which could cause Sidekiq workers to disappear from the Busy
5
+ tab while still being active [#1884]
6
+ - Add "Back to App" button in Web UI. You can set the button link via
7
+ `Sidekiq::Web.app_url = 'http://www.mysite.com'` [#1875, seuros]
8
+ - Add process tag (`-g tag`) to the Busy page so you can differentiate processes at a glance. [seuros, #1878]
9
+ - Add "Kill" button to move retries directly to the DJQ so they don't retry. [seuros, #1867]
10
+
1
11
  3.2.1
2
12
  -----------
3
13
 
@@ -173,7 +183,7 @@ middleware, see 3.0-Upgrade.md.**
173
183
 
174
184
  - Automatically use the config file found at `config/sidekiq.yml`, if not passed `-C`. [#1481]
175
185
  - Store 'retried\_at' and 'failed\_at' timestamps as Floats, not Strings. [#1473]
176
- - A `USR2` signal will now reopen _all_ logs, using IO#reopen. Thus, instead of creating a new Logger object,
186
+ - A `USR2` signal will now reopen _all_ logs, using IO#reopen. Thus, instead of creating a new Logger object,
177
187
  Sidekiq will now just update the existing Logger's file descriptor [#1163].
178
188
  - Remove pidfile when shutting down if started with `-P` [#1470]
179
189
 
@@ -20,6 +20,16 @@ fix or new functionality. Functionality must meet my design goals and
20
20
  vision for the project to be accepted; I would be happy to discuss how
21
21
  your idea can best fit into Sidekiq.
22
22
 
23
- ## Sponsorship
23
+ ## Legal
24
+
25
+ By submitting a Pull Request, you disavow any rights or
26
+ claims to any changes submitted to the Sidekiq project and assign the copyright of
27
+ those changes to Contributed Systems LLC.
28
+
29
+ If you cannot or do not want to reassign those rights (your employment
30
+ contract for your employer may not allow this), you should not submit a PR.
31
+ Open an issue and someone else can do the work.
32
+
33
+ This is a legal way of saying "If you submit a PR to us, that code becomes ours".
34
+ 99.9% of the time that's what you intend anyways; we hope it doesn't scare you away from contributing!
24
35
 
25
- If you've got more money than time and want to sponsor Sidekiq's continued support, your company can buy [Sidekiq Pro](http://sidekiq.org/pro). You get great functionality, I continue to fix bugs and enhance Sidekiq for years to come.
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) Mike Perham
1
+ Copyright (c) Contributed Systems LLC
2
2
 
3
3
  Sidekiq is an Open Source project licensed under the terms of
4
4
  the LGPLv3 license. Please see <http://www.gnu.org/licenses/lgpl-3.0.html>
@@ -3,6 +3,12 @@ Sidekiq Pro Changelog
3
3
 
4
4
  Please see [http://sidekiq.org/pro](http://sidekiq.org/pro) for more details and how to buy.
5
5
 
6
+ 1.7.5
7
+ -----------
8
+
9
+ - Fix job filtering within the Dead tab.
10
+
11
+
6
12
  1.7.4
7
13
  -----------
8
14
 
data/README.md CHANGED
@@ -62,11 +62,9 @@ More Information
62
62
 
63
63
  Please see the [sidekiq wiki](https://github.com/mperham/sidekiq/wiki) for the official documentation.
64
64
  [#sidekiq on irc.freenode.net](irc://irc.freenode.net/#sidekiq) is dedicated to this project,
65
- but bug reports or feature requests suggestions should still go through [issues on Github](https://github.com/mperham/sidekiq/issues). Release announcements are made to [@sidekiq](https://twitter.com/sidekiq)
65
+ but bug reports or feature requests suggestions should still go through [issues on Github](https://github.com/mperham/sidekiq/issues). Release announcements are made to the [@sidekiq](https://twitter.com/sidekiq) Twitter account.
66
66
 
67
- There's also a mailing list via [Librelist](http://librelist.org) that you can subscribe to by sending
68
- an email to <sidekiq@librelist.org> with a greeting in the body. To unsubscribe, send an email to <sidekiq-unsubscribe@librelist.org> and that's it!
69
- Once archiving begins, you'll be able to visit [the archives](http://librelist.com/browser/sidekiq/) to see past threads.
67
+ You may also find useful a [Google Group](https://groups.google.com/forum/#!forum/sidekiq) dedicated to Sidekiq discussion and [a Sidekiq tag](https://stackoverflow.com/questions/tagged/sidekiq) on Stack Overflow.
70
68
 
71
69
 
72
70
  Problems?
@@ -94,4 +92,4 @@ Please see [LICENSE](https://github.com/mperham/sidekiq/blob/master/LICENSE) for
94
92
  Author
95
93
  -----------------
96
94
 
97
- Mike Perham, [@mperham](https://twitter.com/mperham) / [@sidekiq](https://twitter.com/sidekiq), [http://mikeperham.com](http://mikeperham.com)
95
+ Mike Perham, [@mperham](https://twitter.com/mperham) / [@sidekiq](https://twitter.com/sidekiq), [http://mikeperham.com](http://mikeperham.com) / [http://www.contribsys.com](http://www.contribsys.com)
@@ -1,5 +1,7 @@
1
1
  # encoding: utf-8
2
2
  require 'sidekiq/version'
3
+ fail "Sidekiq #{Sidekiq::VERSION} does not support Ruby 1.9." if RUBY_PLATFORM != 'java' && RUBY_VERSION < '2.0.0'
4
+
3
5
  require 'sidekiq/logging'
4
6
  require 'sidekiq/client'
5
7
  require 'sidekiq/worker'
@@ -23,7 +25,7 @@ module Sidekiq
23
25
  :startup => [],
24
26
  :quiet => [],
25
27
  :shutdown => [],
26
- },
28
+ }
27
29
  }
28
30
 
29
31
  def self.❨╯°□°❩╯︵┻━┻
@@ -66,7 +68,7 @@ module Sidekiq
66
68
  end
67
69
 
68
70
  def self.redis(&block)
69
- raise ArgumentError, "requires a block" if !block
71
+ raise ArgumentError, "requires a block" unless block
70
72
  redis_pool.with(&block)
71
73
  end
72
74
 
@@ -143,8 +145,8 @@ module Sidekiq
143
145
  # end
144
146
  # end
145
147
  def self.on(event, &block)
146
- raise ArgumentError, "Symbols only please: #{event}" if !event.is_a?(Symbol)
147
- raise ArgumentError, "Invalid event name: #{event}" if !options[:lifecycle_events].keys.include?(event)
148
+ raise ArgumentError, "Symbols only please: #{event}" unless event.is_a?(Symbol)
149
+ raise ArgumentError, "Invalid event name: #{event}" unless options[:lifecycle_events].keys.include?(event)
148
150
  options[:lifecycle_events][event] << block
149
151
  end
150
152
  end
@@ -316,6 +316,23 @@ module Sidekiq
316
316
  end
317
317
  end
318
318
 
319
+ ##
320
+ # Place job in the dead set
321
+ def kill
322
+ raise 'Kill not available on jobs which have not failed' unless item['failed_at']
323
+ remove_job do |message|
324
+ Sidekiq.logger.info { "Killing job #{message['jid']}" }
325
+ now = Time.now.to_f
326
+ Sidekiq.redis do |conn|
327
+ conn.multi do
328
+ conn.zadd('dead', now, message)
329
+ conn.zremrangebyscore('dead', '-inf', now - DeadSet::DEAD_JOB_TIMEOUT)
330
+ conn.zremrangebyrank('dead', 0, - DeadSet::MAX_JOBS)
331
+ end
332
+ end
333
+ end
334
+ end
335
+
319
336
  private
320
337
 
321
338
  def remove_job
@@ -338,12 +355,13 @@ module Sidekiq
338
355
  false
339
356
  end
340
357
  end
341
- message = hash[true].first
342
- yield message
358
+
359
+ msg = hash.fetch(true, []).first
360
+ yield msg if msg
343
361
 
344
362
  # push the rest back onto the sorted set
345
363
  conn.multi do
346
- hash[false].each do |message|
364
+ hash.fetch(false, []).each do |message|
347
365
  conn.zadd(parent.name, score.to_f.to_s, message)
348
366
  end
349
367
  end
@@ -498,7 +516,13 @@ module Sidekiq
498
516
  end
499
517
  end
500
518
 
519
+ ##
520
+ # Allows enumeration of dead jobs within Sidekiq.
521
+ #
501
522
  class DeadSet < JobSet
523
+ DEAD_JOB_TIMEOUT = 180 * 24 * 60 * 60 # 6 months
524
+ MAX_JOBS = 10_000
525
+
502
526
  def initialize
503
527
  super 'dead'
504
528
  end
@@ -577,6 +601,14 @@ module Sidekiq
577
601
  @attribs = hash
578
602
  end
579
603
 
604
+ def tag
605
+ self['tag']
606
+ end
607
+
608
+ def labels
609
+ Array(self['labels'])
610
+ end
611
+
580
612
  def [](key)
581
613
  @attribs[key]
582
614
  end
@@ -71,14 +71,10 @@ module Sidekiq
71
71
  'queues' => @options[:queues].uniq,
72
72
  'labels' => Sidekiq.options[:labels],
73
73
  }
74
- Sidekiq.redis do |conn|
75
- conn.multi do
76
- conn.sadd('processes', key)
77
- conn.hset(key, 'info', Sidekiq.dump_json(data))
78
- conn.expire(key, 60)
79
- end
80
- end
81
- manager.heartbeat(key, data)
74
+ # this data doesn't change so dump it to a string
75
+ # now so we don't need to dump it every heartbeat.
76
+ json = Sidekiq.dump_json(data)
77
+ manager.heartbeat(key, data, json)
82
78
  end
83
79
 
84
80
  def stop_heartbeat
@@ -89,5 +85,6 @@ module Sidekiq
89
85
  end
90
86
  end
91
87
  end
88
+
92
89
  end
93
90
  end
@@ -132,26 +132,27 @@ module Sidekiq
132
132
  @threads[proxy_id] = thr
133
133
  end
134
134
 
135
- def heartbeat(key, data)
135
+ def heartbeat(key, data, json)
136
136
  proctitle = ['sidekiq', Sidekiq::VERSION]
137
137
  proctitle << data['tag'] unless data['tag'].empty?
138
138
  proctitle << "[#{@busy.size} of #{data['concurrency']} busy]"
139
139
  proctitle << 'stopping' if stopped?
140
140
  $0 = proctitle.join(' ')
141
141
 
142
- ❤(key)
142
+ ❤(key, json)
143
143
  after(5) do
144
- heartbeat(key, data)
144
+ heartbeat(key, data, json)
145
145
  end
146
146
  end
147
147
 
148
148
  private
149
149
 
150
- def ❤(key)
150
+ def ❤(key, json)
151
151
  begin
152
- _, _, msg = Sidekiq.redis do |conn|
152
+ _, _, _, msg = Sidekiq.redis do |conn|
153
153
  conn.multi do
154
- conn.hmset(key, 'busy', @busy.size, 'beat', Time.now.to_f)
154
+ conn.sadd('processes', key)
155
+ conn.hmset(key, 'info', json, 'busy', @busy.size, 'beat', Time.now.to_f)
155
156
  conn.expire(key, 60)
156
157
  conn.rpop("#{key}-signals")
157
158
  end
@@ -6,21 +6,22 @@ module Sidekiq
6
6
  ##
7
7
  # Automatically retry jobs that fail in Sidekiq.
8
8
  # Sidekiq's retry support assumes a typical development lifecycle:
9
- # 0. push some code changes with a bug in it
10
- # 1. bug causes message processing to fail, sidekiq's middleware captures
11
- # the message and pushes it onto a retry queue
12
- # 2. sidekiq retries messages in the retry queue multiple times with
13
- # an exponential delay, the message continues to fail
14
- # 3. after a few days, a developer deploys a fix. the message is
15
- # reprocessed successfully.
16
- # 4. if 3 never happens, sidekiq will eventually give up and throw the
17
- # message away. If the worker defines a method called 'retries_exhausted',
18
- # this will be called before throwing the message away. If the
19
- # 'retries_exhausted' method throws an exception, it's dropped and logged.
20
9
  #
21
- # A message looks like:
10
+ # 0. push some code changes with a bug in it
11
+ # 1. bug causes job processing to fail, sidekiq's middleware captures
12
+ # the job and pushes it onto a retry queue
13
+ # 2. sidekiq retries jobs in the retry queue multiple times with
14
+ # an exponential delay, the job continues to fail
15
+ # 3. after a few days, a developer deploys a fix. the job is
16
+ # reprocessed successfully.
17
+ # 4. once retries are exhausted, sidekiq will give up and move the
18
+ # job to the Dead Job Queue (aka morgue) where it must be dealt with
19
+ # manually in the Web UI.
20
+ # 5. After 6 months on the DJQ, Sidekiq will discard the job.
22
21
  #
23
- # { 'class' => 'HardWorker', 'args' => [1, 2, 'foo'] }
22
+ # A job looks like:
23
+ #
24
+ # { 'class' => 'HardWorker', 'args' => [1, 2, 'foo'], 'retry' => true }
24
25
  #
25
26
  # The 'retry' option also accepts a number (in place of 'true'):
26
27
  #
@@ -29,7 +30,7 @@ module Sidekiq
29
30
  # The job will be retried this number of times before giving up. (If simply
30
31
  # 'true', Sidekiq retries 25 times)
31
32
  #
32
- # We'll add a bit more data to the message to support retries:
33
+ # We'll add a bit more data to the job to support retries:
33
34
  #
34
35
  # * 'queue' - the queue to use
35
36
  # * 'retry_count' - number of times we've retried so far.
@@ -37,18 +38,28 @@ module Sidekiq
37
38
  # * 'error_class' - the exception class
38
39
  # * 'failed_at' - the first time it failed
39
40
  # * 'retried_at' - the last time it was retried
41
+ # * 'backtrace' - the number of lines of error backtrace to store
40
42
  #
41
- # We don't store the backtrace as that can add a lot of overhead
42
- # to the message and everyone is using Airbrake, right?
43
+ # We don't store the backtrace by default as that can add a lot of overhead
44
+ # to the job and everyone is using an error service, right?
43
45
  #
44
- # The default number of retry attempts is 25. You can pass a value for the
45
- # number of retry attempts when adding the middleware using the options hash:
46
+ # The default number of retry attempts is 25 which works out to about 3 weeks
47
+ # of retries. You can pass a value for the max number of retry attempts when
48
+ # adding the middleware using the options hash:
46
49
  #
47
50
  # Sidekiq.configure_server do |config|
48
51
  # config.server_middleware do |chain|
49
52
  # chain.add Middleware::Server::RetryJobs, :max_retries => 7
50
53
  # end
51
54
  # end
55
+ #
56
+ # or limit the number of retries for a particular worker with:
57
+ #
58
+ # class MyWorker
59
+ # include Sidekiq::Worker
60
+ # sidekiq_options :retry => 10
61
+ # end
62
+ #
52
63
  class RetryJobs
53
64
  include Sidekiq::Util
54
65
 
@@ -75,7 +86,7 @@ module Sidekiq
75
86
  else
76
87
  queue
77
88
  end
78
- msg['error_message'] = e.message
89
+ msg['error_message'] = e.message[0..10_000]
79
90
  msg['error_class'] = e.class.name
80
91
  count = if msg['retry_count']
81
92
  msg['retried_at'] = Time.now.to_f
@@ -134,8 +145,8 @@ module Sidekiq
134
145
  Sidekiq.redis do |conn|
135
146
  conn.multi do
136
147
  conn.zadd('dead', now, payload)
137
- conn.zremrangebyscore('dead', '-inf', now - DEAD_JOB_TIMEOUT)
138
- conn.zremrangebyrank('dead', 0, -MAX_JOBS)
148
+ conn.zremrangebyscore('dead', '-inf', now - DeadSet::DEAD_JOB_TIMEOUT)
149
+ conn.zremrangebyrank('dead', 0, -DeadSet::MAX_JOBS)
139
150
  end
140
151
  end
141
152
  end
@@ -51,7 +51,10 @@ module Sidekiq
51
51
  logger.error ex.backtrace.first
52
52
  end
53
53
 
54
- after(poll_interval * rand) { poll }
54
+ # Randomizing scales the interval by half since
55
+ # on average calling `rand` returns 0.5.
56
+ # We make up for this by doubling the interval
57
+ after(poll_interval * 2 * rand) { poll }
55
58
  end
56
59
  end
57
60
 
@@ -73,7 +76,7 @@ module Sidekiq
73
76
  def poll_interval
74
77
  Sidekiq.options[:poll_interval] ||= begin
75
78
  pcount = Sidekiq.redis {|c| c.scard('processes') } || 1
76
- pcount * 15 * 2
79
+ pcount * 15
77
80
  end
78
81
  end
79
82
 
@@ -1,3 +1,3 @@
1
1
  module Sidekiq
2
- VERSION = "3.2.1"
2
+ VERSION = "3.2.2"
3
3
  end
@@ -36,6 +36,8 @@ module Sidekiq
36
36
  @custom_tabs ||= {}
37
37
  end
38
38
  alias_method :tabs, :custom_tabs
39
+
40
+ attr_accessor :app_url
39
41
  end
40
42
 
41
43
  get "/busy" do
@@ -100,7 +102,7 @@ module Sidekiq
100
102
 
101
103
  params['key'].each do |key|
102
104
  job = Sidekiq::DeadSet.new.fetch(*parse_params(key)).first
103
- retry_or_delete job, params if job
105
+ retry_or_delete_or_kill job, params if job
104
106
  end
105
107
  redirect_with_query("#{root_path}morgue")
106
108
  end
@@ -118,7 +120,7 @@ module Sidekiq
118
120
  post "/morgue/:key" do
119
121
  halt 404 unless params['key']
120
122
  job = Sidekiq::DeadSet.new.fetch(*parse_params(params['key'])).first
121
- retry_or_delete job, params if job
123
+ retry_or_delete_or_kill job, params if job
122
124
  redirect_with_query("#{root_path}morgue")
123
125
  end
124
126
 
@@ -142,7 +144,7 @@ module Sidekiq
142
144
 
143
145
  params['key'].each do |key|
144
146
  job = Sidekiq::RetrySet.new.fetch(*parse_params(key)).first
145
- retry_or_delete job, params if job
147
+ retry_or_delete_or_kill job, params if job
146
148
  end
147
149
  redirect_with_query("#{root_path}retries")
148
150
  end
@@ -160,7 +162,7 @@ module Sidekiq
160
162
  post "/retries/:key" do
161
163
  halt 404 unless params['key']
162
164
  job = Sidekiq::RetrySet.new.fetch(*parse_params(params['key'])).first
163
- retry_or_delete job, params if job
165
+ retry_or_delete_or_kill job, params if job
164
166
  redirect_with_query("#{root_path}retries")
165
167
  end
166
168
 
@@ -196,7 +198,7 @@ module Sidekiq
196
198
  end
197
199
 
198
200
  get '/' do
199
- @redis_info = Sidekiq.redis { |conn| conn.info }.select{ |k, v| REDIS_KEYS.include? k }
201
+ @redis_info = redis_info.select{ |k, v| REDIS_KEYS.include? k }
200
202
  stats_history = Sidekiq::Stats::History.new((params[:days] || 30).to_i)
201
203
  @processed_history = stats_history.processed
202
204
  @failed_history = stats_history.failed
@@ -208,7 +210,7 @@ module Sidekiq
208
210
  get '/dashboard/stats' do
209
211
  sidekiq_stats = Sidekiq::Stats.new
210
212
  queue = Sidekiq::Queue.new
211
- redis_stats = Sidekiq.redis { |conn| conn.info }.select{ |k, v| REDIS_KEYS.include? k }
213
+ redis_stats = redis_info.select{ |k, v| REDIS_KEYS.include? k }
212
214
 
213
215
  content_type :json
214
216
  Sidekiq.dump_json({
@@ -227,11 +229,13 @@ module Sidekiq
227
229
 
228
230
  private
229
231
 
230
- def retry_or_delete job, params
232
+ def retry_or_delete_or_kill job, params
231
233
  if params['retry']
232
234
  job.retry
233
235
  elsif params['delete']
234
236
  job.delete
237
+ elsif params['kill']
238
+ job.kill
235
239
  end
236
240
  end
237
241
 
@@ -68,6 +68,18 @@ module Sidekiq
68
68
  @@ns ||= Sidekiq.redis {|conn| conn.respond_to?(:namespace) ? conn.namespace : nil }
69
69
  end
70
70
 
71
+ def redis_info
72
+ Sidekiq.redis do |conn|
73
+ # admin commands can't go through redis-namespace starting
74
+ # in redis-namespace 2.0
75
+ if conn.respond_to?(:namespace)
76
+ conn.redis.info
77
+ else
78
+ conn.info
79
+ end
80
+ end
81
+ end
82
+
71
83
  def root_path
72
84
  "#{env['SCRIPT_NAME']}/"
73
85
  end
@@ -104,7 +104,7 @@ class TestManager < Sidekiq::Test
104
104
 
105
105
  describe 'when manager is active' do
106
106
  before do
107
- @mgr.heartbeat('identity', heartbeat_data)
107
+ @mgr.heartbeat('identity', heartbeat_data, Sidekiq.dump_json(heartbeat_data))
108
108
  end
109
109
 
110
110
  it 'sets useful info to proctitle' do
@@ -126,7 +126,7 @@ class TestManager < Sidekiq::Test
126
126
 
127
127
  @mgr.stop
128
128
  @mgr.processor_done(@processor)
129
- @mgr.heartbeat('identity', heartbeat_data)
129
+ @mgr.heartbeat('identity', heartbeat_data, Sidekiq.dump_json(heartbeat_data))
130
130
 
131
131
  @processor.verify
132
132
  end
@@ -173,6 +173,17 @@ class TestWeb < Sidekiq::Test
173
173
  assert_match(/#{params.first['args'][2]}/, last_response.body)
174
174
  end
175
175
 
176
+ it 'can kill a single retry now' do
177
+ params = add_retry
178
+ post "/retries/#{job_params(*params)}", 'kill' => 'Kill'
179
+ assert_equal 302, last_response.status
180
+ assert_equal 'http://example.org/retries', last_response.header['Location']
181
+
182
+ get '/morgue'
183
+ assert_equal 200, last_response.status
184
+ assert_match(/#{params.first['args'][2]}/, last_response.body)
185
+ end
186
+
176
187
  it 'can display scheduled' do
177
188
  get '/scheduled'
178
189
  assert_equal 200, last_response.status
@@ -102,7 +102,7 @@ header.row .pagination {
102
102
  border-width: 0;
103
103
  }
104
104
  .poll-wrapper {
105
- margin: 9px 0;
105
+ margin: 9px;
106
106
  }
107
107
  .nav #live-poll {
108
108
  height: 25px;
@@ -604,10 +604,6 @@ div.interval-slider input {
604
604
  }
605
605
 
606
606
  @media (max-width: 768px) {
607
- .navbar .container {
608
- text-align: center
609
- }
610
-
611
607
  .navbar .navbar-brand {
612
608
  float: none;
613
609
  display: block;
@@ -629,7 +625,13 @@ div.interval-slider input {
629
625
  }
630
626
 
631
627
  .poll-wrapper {
632
- margin: 0 9px 9px;
628
+ width: 100%;
629
+ text-align: center;
630
+ }
631
+
632
+ .poll-wrapper > a {
633
+ display: inline-block;
634
+ margin: 5px;
633
635
  }
634
636
 
635
637
  .navbar.navbar-fixed-bottom ul {
@@ -33,6 +33,7 @@ de:
33
33
  NextRetry: Nächster Versuch
34
34
  RetryCount: Anzahl der Versuche
35
35
  RetryNow: Jetzt erneut versuchen
36
+ Kill: Töten
36
37
  LastRetry: Letzter Versuch
37
38
  OriginallyFailed: Ursprünglich fehlgeschlagen
38
39
  AreYouSure: Bist du sicher?
@@ -33,6 +33,7 @@ en: # <---- change this to your locale code
33
33
  NextRetry: Next Retry
34
34
  RetryCount: Retry Count
35
35
  RetryNow: Retry Now
36
+ Kill: Kill
36
37
  LastRetry: Last Retry
37
38
  OriginallyFailed: Originally Failed
38
39
  AreYouSure: Are you sure?
@@ -33,6 +33,7 @@ es:
33
33
  NextRetry: Siguiente Intento
34
34
  RetryCount: Numero de Reintentos
35
35
  RetryNow: Reintentar Ahora
36
+ Kill: Matar
36
37
  LastRetry: Último Reintento
37
38
  OriginallyFailed: Falló Originalmente
38
39
  AreYouSure: ¿Estás seguro?
@@ -33,6 +33,7 @@ fr:
33
33
  NextRetry: Prochain essai
34
34
  RetryCount: Nombre d'essais
35
35
  RetryNow: Réessayer maintenant
36
+ Kill: Tuer
36
37
  LastRetry: Dernier essai
37
38
  OriginallyFailed: Échec originel
38
39
  AreYouSure: Êtes-vous certain ?
@@ -33,6 +33,7 @@ it:
33
33
  NextRetry: Prossimo tentativo
34
34
  RetryCount: Totale tentativi
35
35
  RetryNow: Riprova
36
+ Kill: Uccidere
36
37
  LastRetry: Ultimo tentativo
37
38
  OriginallyFailed: Primo fallimento
38
39
  AreYouSure: Sei sicuro?
@@ -32,6 +32,7 @@ ru:
32
32
  NextRetry: Следующая попытка
33
33
  RetryCount: Кол-во попыток
34
34
  RetryNow: Повторить сейчас
35
+ Kill: Убиваем
35
36
  LastRetry: Последняя попытка
36
37
  OriginallyFailed: Первый провал
37
38
  AreYouSure: Вы уверены?
@@ -0,0 +1,22 @@
1
+ <div class="navbar navbar-fixed-bottom navbar-inverse">
2
+ <div class="navbar-inner">
3
+ <div class="container text-center">
4
+ <ul class="nav">
5
+ <li>
6
+ <p class="navbar-text" style="color:white;">Sidekiq v<%= Sidekiq::VERSION %></p>
7
+ </li>
8
+ <li>
9
+ <p class="navbar-text">Redis: <%= redis_connection %></p>
10
+ </li>
11
+ <li>
12
+ <p class="navbar-text"><%= t('Time') %>: <%= Time.now.utc.strftime('%H:%M:%S UTC') %></p>
13
+ </li>
14
+ <% if namespace %>
15
+ <li>
16
+ <p class="navbar-text"><%= t('Namespace') %>: <%= namespace %></p>
17
+ </li>
18
+ <% end %>
19
+ </ul>
20
+ </div>
21
+ </div>
22
+ </div>
@@ -1,30 +1,34 @@
1
- <div class="navbar-inner">
2
- <div class="container">
3
- <a class="navbar-brand" href="<%= root_path %>">
4
- <%= Sidekiq::NAME %>
5
- <%= erb :_status %>
6
- </a>
7
- <ul class="nav navbar-nav">
8
- <% Sidekiq::Web.default_tabs.each do |title, url| %>
9
- <% if url == '' %>
10
- <li class="<%= current_path == url ? 'active' : '' %>">
11
- <a href="<%= root_path %><%= url %>"><%= t(title) %></a>
12
- </li>
13
- <% else %>
14
- <li class="<%= current_path.start_with?(url) ? 'active' : '' %>">
15
- <a href="<%= root_path %><%= url %>"><%= t(title) %></a>
16
- </li>
17
- <% end %>
18
- <% end %>
19
- <% Sidekiq::Web.custom_tabs.each do |title, url| %>
20
- <li class="<%= current_path.start_with?(url) ? 'active' : '' %>">
21
- <a href="<%= root_path %><%= url %>"><%= t(title) %></a>
22
- </li>
23
- <% end %>
24
- </ul>
25
-
1
+ <div class="navbar navbar-default navbar-fixed-top">
2
+ <div class="navbar-inner">
3
+ <div class="container-fluid text-center">
4
+ <a class="navbar-brand" href="<%= root_path %>">
5
+ <%= Sidekiq::NAME %>
6
+ <%= erb :_status %>
7
+ </a>
8
+ <ul class="nav navbar-nav">
9
+ <% Sidekiq::Web.default_tabs.each do |title, url| %>
10
+ <% if url == '' %>
11
+ <li class="<%= current_path == url ? 'active' : '' %>">
12
+ <a href="<%= root_path %><%= url %>"><%= t(title) %></a>
13
+ </li>
14
+ <% else %>
15
+ <li class="<%= current_path.start_with?(url) ? 'active' : '' %>">
16
+ <a href="<%= root_path %><%= url %>"><%= t(title) %></a>
17
+ </li>
18
+ <% end %>
19
+ <% end %>
20
+ <% Sidekiq::Web.custom_tabs.each do |title, url| %>
21
+ <li class="<%= current_path.start_with?(url) ? 'active' : '' %>">
22
+ <a href="<%= root_path %><%= url %>"><%= t(title) %></a>
23
+ </li>
24
+ <% end %>
25
+ </ul>
26
+ </div>
26
27
  <div class="poll-wrapper pull-right">
27
- <%= erb :_poll %>
28
+ <%= erb :_poll %>
29
+ <% if Sidekiq::Web.app_url %>
30
+ <a class="btn btn-inverse" href="<%= Sidekiq::Web.app_url %>">Back to App</a>
31
+ <% end %>
28
32
  </div>
29
33
  </div>
30
34
  </div>
@@ -1,10 +1,8 @@
1
- <% if params[:poll] %>
2
- <script>
3
- setInterval("window.location.reload(true)", parseInt(localStorage.timeInterval) || 2000);
4
- </script>
5
- <% end %>
6
- <% unless current_path == '' %>
1
+ <% if current_path != '' %>
7
2
  <% if params[:poll] %>
3
+ <script>
4
+ setInterval("window.location.reload(true)", parseInt(localStorage.timeInterval) || 2000);
5
+ </script>
8
6
  <a id="live-poll" class="btn btn-primary active" href="<%= root_path %><%= current_path %>"><%= t('StopPolling') %></a>
9
7
  <% else %>
10
8
  <a id="live-poll" class="btn btn-primary" href="<%= root_path %><%= current_path %>?<%= qparams(poll: true) %>"><%= t('LivePoll') %></a>
@@ -21,11 +21,12 @@
21
21
  <th><%= t('Busy') %></th>
22
22
  <th>&nbsp;</th>
23
23
  </thead>
24
- <% Sidekiq::ProcessSet.new.each_with_index do |process, index| %>
24
+ <% Sidekiq::ProcessSet.new.each do |process| %>
25
25
  <tr>
26
26
  <td>
27
27
  <%= "#{process['hostname']}:#{process['pid']}" %>
28
- <% Array(process['labels']).each do |label| %>
28
+ <span class="label label-success"><%= process.tag %></span>
29
+ <% process.labels.each do |label| %>
29
30
  <span class="label label-info"><%= label %></span>
30
31
  <% end %>
31
32
  </td>
@@ -15,18 +15,23 @@
15
15
  </div>
16
16
  </div>
17
17
 
18
- <div id="realtime" data-processed-label="<%= t('Processed') %>" data-failed-label="<%= t('Failed') %>"></div>
19
- <div id="realtime-legend"></div>
18
+ <div class="row">
19
+ <div id="realtime" data-processed-label="<%= t('Processed') %>" data-failed-label="<%= t('Failed') %>"></div>
20
+ <div id="realtime-legend"></div>
21
+ </div>
22
+
23
+ <div class="row">
24
+ <h5>
25
+ <span class="history-heading"><%= t('History') %></span>
26
+ <a href="<%= root_path %>?days=7" class="history-graph <%= "active" if params[:days] == "7" %>"><%= t('OneWeek') %></a>
27
+ <a href="<%= root_path %>" class="history-graph <%= "active" if params[:days].nil? || params[:days] == "30" %>"><%= t('OneMonth') %></a>
28
+ <a href="<%= root_path %>?days=90" class="history-graph <%= "active" if params[:days] == "90" %>"><%= t('ThreeMonths') %></a>
29
+ <a href="<%= root_path %>?days=180" class="history-graph <%= "active" if params[:days] == "180" %>"><%= t('SixMonths') %></a>
30
+ </h5>
20
31
 
21
- <h5>
22
- <span class="history-heading"><%= t('History') %></span>
23
- <a href="<%= root_path %>?days=7" class="history-graph <%= "active" if params[:days] == "7" %>"><%= t('OneWeek') %></a>
24
- <a href="<%= root_path %>" class="history-graph <%= "active" if params[:days].nil? || params[:days] == "30" %>" ><%= t('OneMonth') %></a>
25
- <a href="<%= root_path %>?days=90" class="history-graph <%= "active" if params[:days] == "90" %>"><%= t('ThreeMonths') %></a>
26
- <a href="<%= root_path %>?days=180" class="history-graph <%= "active" if params[:days] == "180" %>"><%= t('SixMonths') %></a>
27
- </h5>
28
- <div id="history" data-processed-label="<%= t('Processed') %>" data-failed-label="<%= t('Failed') %>" data-processed="<%= h Sidekiq.dump_json(@processed_history) %>" data-failed="<%= h Sidekiq.dump_json(@failed_history) %>" data-update-url="<%= root_path %>dashboard/stats"></div>
29
- <div id="history-legend"></div>
32
+ <div id="history" data-processed-label="<%= t('Processed') %>" data-failed-label="<%= t('Failed') %>" data-processed="<%= h Sidekiq.dump_json(@processed_history) %>" data-failed="<%= h Sidekiq.dump_json(@failed_history) %>" data-update-url="<%= root_path %>dashboard/stats"></div>
33
+ <div id="history-legend"></div>
34
+ </div>
30
35
 
31
36
  <br/>
32
37
  <h5>Redis</h5>
@@ -7,13 +7,10 @@
7
7
  <link href="<%= root_path %>stylesheets/application.css" media="screen" rel="stylesheet" type="text/css" />
8
8
  <script type="text/javascript" src="<%= root_path %>javascripts/application.js"></script>
9
9
  <script type="text/javascript" src="<%= root_path %>javascripts/locales/jquery.timeago.<%= locale %>.js"></script>
10
- <meta name="google" value="notranslate" />
10
+ <meta name="google" content="notranslate" />
11
11
  </head>
12
12
  <body class="admin">
13
- <div class="navbar navbar-default navbar-fixed-top">
14
- <%= erb :_nav %>
15
- </div>
16
-
13
+ <%= erb :_nav %>
17
14
  <div id="page">
18
15
  <div class="container">
19
16
  <div class="row">
@@ -27,28 +24,6 @@
27
24
  </div>
28
25
  </div>
29
26
  </div>
30
-
31
- <div class="navbar navbar-fixed-bottom navbar-inverse">
32
- <div class="navbar-inner">
33
- <div class="container">
34
- <ul class="nav">
35
- <li>
36
- <p class="navbar-text" style="color:white;">Sidekiq v<%= Sidekiq::VERSION %></p>
37
- </li>
38
- <li>
39
- <p class="navbar-text">Redis: <%= redis_connection %></p>
40
- </li>
41
- <li>
42
- <p class="navbar-text"><%= t('Time') %>: <%= Time.now.utc.strftime('%H:%M:%S UTC') %></p>
43
- </li>
44
- <% if namespace %>
45
- <li>
46
- <p class="navbar-text"><%= t('Namespace') %>: <%= namespace %></p>
47
- </li>
48
- <% end %>
49
- </ul>
50
- </div>
51
- </div>
52
- </div>
27
+ <%= erb :_footer %>
53
28
  </body>
54
29
  </html>
@@ -54,6 +54,7 @@
54
54
  </table>
55
55
  <input class="btn btn-primary btn-xs pull-left" type="submit" name="retry" value="<%= t('RetryNow') %>" />
56
56
  <input class="btn btn-danger btn-xs pull-left" type="submit" name="delete" value="<%= t('Delete') %>" />
57
+ <input class="btn btn-danger btn-xs pull-left" type="submit" name="kill" value="<%= t('Kill') %>" />
57
58
  </form>
58
59
 
59
60
  <form action="<%= root_path %>retries/all/delete" method="post">
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.1
4
+ version: 3.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Perham
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-08 00:00:00.000000000 Z
11
+ date: 2014-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -302,6 +302,7 @@ files:
302
302
  - web/locales/sv.yml
303
303
  - web/locales/zh-cn.yml
304
304
  - web/locales/zh-tw.yml
305
+ - web/views/_footer.erb
305
306
  - web/views/_job_info.erb
306
307
  - web/views/_nav.erb
307
308
  - web/views/_paging.erb