sidekiq 2.4.0 → 2.5.0

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.

Files changed (62) hide show
  1. data/.gitignore +1 -0
  2. data/Changes.md +11 -0
  3. data/Gemfile +6 -0
  4. data/lib/sidekiq.rb +1 -0
  5. data/lib/sidekiq/api.rb +184 -0
  6. data/lib/sidekiq/cli.rb +3 -2
  7. data/lib/sidekiq/client.rb +16 -10
  8. data/lib/sidekiq/core_ext.rb +30 -0
  9. data/lib/sidekiq/exception_handler.rb +9 -0
  10. data/lib/sidekiq/processor.rb +1 -1
  11. data/lib/sidekiq/testing/inline.rb +3 -3
  12. data/lib/sidekiq/util.rb +1 -11
  13. data/lib/sidekiq/version.rb +1 -1
  14. data/lib/sidekiq/web.rb +49 -1
  15. data/lib/sidekiq/worker.rb +3 -9
  16. data/sidekiq.gemspec +3 -0
  17. data/test/config.yml +1 -1
  18. data/test/test_api.rb +75 -0
  19. data/test/test_cli.rb +6 -1
  20. data/test/test_exception_handler.rb +16 -0
  21. data/test/test_testing_inline.rb +3 -3
  22. data/test/test_web.rb +27 -6
  23. data/web/assets/images/bootstrap/glyphicons-halflings-white.png +0 -0
  24. data/web/assets/images/bootstrap/glyphicons-halflings.png +0 -0
  25. data/web/assets/images/logo.png +0 -0
  26. data/web/assets/images/status-sd8051fd480.png +0 -0
  27. data/web/assets/images/status/active.png +0 -0
  28. data/web/assets/images/status/idle.png +0 -0
  29. data/web/assets/javascripts/application.js +44 -16
  30. data/web/assets/javascripts/vendor/bootstrap.js +0 -0
  31. data/web/assets/javascripts/vendor/jquery.js +0 -0
  32. data/web/assets/javascripts/vendor/jquery.timeago.js +0 -0
  33. data/web/assets/stylesheets/application.css +1 -3
  34. data/web/assets/stylesheets/layout.css +0 -0
  35. data/web/assets/stylesheets/partials/_base.scss +116 -0
  36. data/web/assets/stylesheets/partials/_colors.scss +46 -0
  37. data/web/assets/stylesheets/partials/_fonts.scss +3 -0
  38. data/web/assets/stylesheets/partials/_h5bp.scss +293 -0
  39. data/web/assets/stylesheets/partials/_layout.scss +197 -0
  40. data/web/assets/stylesheets/partials/_navbar.scss +100 -0
  41. data/web/assets/stylesheets/partials/_normalize.scss +504 -0
  42. data/web/assets/stylesheets/partials/_prettify.css +30 -0
  43. data/web/assets/stylesheets/partials/_variables.scss +28 -0
  44. data/web/assets/stylesheets/public.scss +74 -0
  45. data/web/assets/stylesheets/style.scss +69 -0
  46. data/web/assets/stylesheets/vendor/bootstrap-responsive.css +0 -0
  47. data/web/assets/stylesheets/vendor/bootstrap.css +0 -0
  48. data/web/assets/stylesheets/vendors.scss +2 -0
  49. data/web/views/_nav.slim +13 -0
  50. data/web/views/_paging.slim +0 -0
  51. data/web/views/_status.slim +3 -0
  52. data/web/views/_summary.slim +19 -8
  53. data/web/views/_workers.slim +12 -5
  54. data/web/views/index.slim +8 -9
  55. data/web/views/layout.slim +27 -19
  56. data/web/views/poll.slim +1 -0
  57. data/web/views/queue.slim +22 -9
  58. data/web/views/queues.slim +7 -7
  59. data/web/views/retries.slim +13 -10
  60. data/web/views/retry.slim +5 -5
  61. data/web/views/scheduled.slim +13 -10
  62. metadata +71 -2
@@ -0,0 +1,30 @@
1
+ .com { color: #93a1a1; }
2
+ .lit { color: #195f91; }
3
+ .pun, .opn, .clo { color: #93a1a1; }
4
+ .fun { color: #dc322f; }
5
+ .str, .atv { color: #D14; }
6
+ .kwd, .linenums .tag { color: #1e347b; }
7
+ .typ, .atn, .dec, .var { color: teal; }
8
+ .pln { color: #48484c; }
9
+
10
+ .prettyprint {
11
+ padding: 8px;
12
+ background-color: #f7f7f9;
13
+ border: 1px solid #e9e9e9;
14
+ }
15
+ .prettyprint.linenums {
16
+ -webkit-box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0;
17
+ -moz-box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0;
18
+ box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0;
19
+ }
20
+
21
+ /* Specify class=linenums on a pre to get line numbering */
22
+ ol.linenums {
23
+ margin: 0 0 0 33px; /* IE indents via margin-left */
24
+ }
25
+ ol.linenums li {
26
+ padding-left: 12px;
27
+ color: #bebec5;
28
+ line-height: 18px;
29
+ text-shadow: 0 1px 0 #fff;
30
+ }
@@ -0,0 +1,28 @@
1
+ /* susy config */
2
+ /* see http://susy.oddbird.net/guides/reference/ */
3
+ $total-columns: 12;
4
+ $column-width: 4.5em;
5
+ $gutter-width: 1em;
6
+ $grid-padding: $gutter-width;
7
+ $border-box-sizing: true;
8
+ $base-font-size: 13px;
9
+ $base-line-height: 20px;
10
+ $breakpoint: 0em 45em; /* min-max media query breakpoint */
11
+ $from-direction: left;
12
+ $omega-float: $from-direction;
13
+
14
+
15
+ /* column shortcuts */
16
+ $one-third: $total-columns / 3;
17
+ $two-thirds: $one-third * 2;
18
+ $half: $total-columns / 2;
19
+ $one-fourth: $total-columns / 4;
20
+
21
+ /* colors */
22
+ $black: #292724;
23
+ $bg-color: #f3f3f3;
24
+
25
+ /* others */
26
+ $font-size: $base-font-size;
27
+ $line-height: $base-line-height;
28
+ $container-padding: $base-line-height;
@@ -0,0 +1,74 @@
1
+ .public{
2
+ .title{
3
+ position:relative;
4
+ &.reset{
5
+ .image{
6
+ position:relative;
7
+ text-indent:-1400px;
8
+ }
9
+ .text{
10
+ @include transform(rotate(0deg));
11
+ }
12
+ }
13
+ .image{
14
+ display:inline-block;
15
+ text-indent:0;
16
+ img{
17
+ max-width:none;
18
+ }
19
+
20
+ @include transition(all $kick_time ease-out);
21
+ }
22
+ .text{
23
+ display:inline-block;
24
+ @include transition(all $kick_time ease-out $kick_time*0.90);
25
+
26
+ @include transform(rotate(2deg));
27
+ }
28
+ }
29
+ &.csstransforms3d{
30
+ .title{
31
+ margin:0 auto;
32
+ width: 450px;
33
+ @media (max-width: $split_width) {
34
+ width: 280px;
35
+ .logo{
36
+ width: 60px;
37
+ }
38
+ }
39
+
40
+ &.reset{
41
+ .image{
42
+ text-indent:0;
43
+ @include transform3d(translateX(-1000px));
44
+ }
45
+ .text{
46
+ @include transform3d(translateX(0px) rotate(0deg));
47
+ }
48
+ }
49
+ .image{
50
+ position:absolute;
51
+ top: 0;
52
+ left:0;
53
+ @include transform3d(translateX(0px));
54
+ img{
55
+ position:absolute;
56
+ top: 0;
57
+ left:0;
58
+ }
59
+ }
60
+ .text{
61
+ @include transform3d(translateX(35px) rotateZ(2deg));
62
+ }
63
+ }
64
+ }
65
+ .navbar-inner{
66
+ @include border-radius(0);
67
+ border-left:0;
68
+ border-right:0;
69
+ @media (max-width: $split_width) {
70
+ padding:0;
71
+ }
72
+ }
73
+ }
74
+
@@ -0,0 +1,69 @@
1
+ $split_width: 500px;
2
+
3
+ @import 'compass';
4
+
5
+ @import 'partials/fonts';
6
+ @import 'partials/colors';
7
+ @import 'partials/variables';
8
+ @import 'partials/base';
9
+ @import 'partials/layout';
10
+ @import 'partials/prettify';
11
+
12
+ @import 'partials/navbar';
13
+
14
+ $kick_time : 0.2s;
15
+
16
+ $status_spacing: 50px;
17
+ @import 'status/*.png';
18
+ @include all-status-sprites;
19
+
20
+
21
+ .btn{
22
+ font-weight: 700;
23
+ border : none;
24
+ @include border-radius(3px);
25
+ @include box-shadow($smooth_shadow);
26
+ @include background-image($btn_gradient);
27
+ &:hover{
28
+ background-color:$btn_dark;
29
+ }
30
+ }
31
+
32
+ .btn-primary{
33
+ @include background-image($btn_primary_gradient);
34
+ &:hover{
35
+ background-color:$btn_primary_dark;
36
+ }
37
+ }
38
+
39
+ .btn-danger{
40
+ @include background-image($btn_danger_gradient);
41
+ &:hover{
42
+ background-color:$btn_danger_dark;
43
+ }
44
+ }
45
+
46
+ .poll-status{
47
+ padding:10px 0;
48
+ }
49
+
50
+ // .status_idle{
51
+ // @include background-image('images/status/idle.png');
52
+ // }
53
+
54
+ @mixin status_size($icon){
55
+ $height: status-sprite-height($icon);
56
+ $width : status-sprite-width($icon);
57
+ height : $height;
58
+ width : $width;
59
+ display: inline-block;
60
+ }
61
+
62
+ .status-idle{
63
+ @include status_size('idle');
64
+ }
65
+ .status-active{
66
+ @include status_size('active');
67
+ }
68
+
69
+ @import 'public';
@@ -0,0 +1,2 @@
1
+ //= require vendor/bootstrap
2
+ //= require vendor/bootstrap-responsive
@@ -0,0 +1,13 @@
1
+ .navbar-inner
2
+ .container
3
+ a.btn.btn-navbar data-toggle="collapse" data-target=".nav-collapse"
4
+ span.icon-bar
5
+ span.icon-bar
6
+ span.icon-bar
7
+ a.brand href='#{{root_path}}'
8
+ = Sidekiq::NAME
9
+ div.nav-collapse
10
+ ul.nav
11
+ - tabs.each do |title, url|
12
+ li class="#{(current_path==url) ? 'active':''}"
13
+ a href='#{{root_path}}#{{url}}' #{title}
File without changes
@@ -0,0 +1,3 @@
1
+ span.status
2
+ i class="status-sprite status-#{current_status}"
3
+ == current_status
@@ -1,8 +1,19 @@
1
- .hero-unit
2
- h1 Sidekiq is #{current_status}
3
- p Processed: #{number_with_delimiter(processed)}
4
- p Failed: #{number_with_delimiter(failed)}
5
- p Busy Workers: #{number_with_delimiter(workers.size)}
6
- p Scheduled: #{number_with_delimiter(zcard('schedule'))}
7
- p Retries Pending: #{number_with_delimiter(zcard('retry'))}
8
- p Queue Backlog: #{number_with_delimiter(backlog)}
1
+ ul.unstyled.summary
2
+ li
3
+ span.count #{number_with_delimiter(processed)}
4
+ span.desc Processed
5
+ li
6
+ span.count #{number_with_delimiter(failed)}
7
+ span.desc Failed
8
+ li
9
+ span.count #{number_with_delimiter(workers.size)}
10
+ span.desc Busy
11
+ li
12
+ span.count #{number_with_delimiter(zcard('schedule'))}
13
+ span.desc Scheduled
14
+ li
15
+ span.count #{number_with_delimiter(zcard('retry'))}
16
+ span.desc Retries
17
+ li
18
+ span.count #{number_with_delimiter(backlog)}
19
+ span.desc Queue
@@ -1,14 +1,21 @@
1
- table class="table table-striped table-bordered workers"
2
- tr
1
+ table class="workers table table-hover table-bordered table-striped table-white"
2
+ thead
3
3
  th Worker
4
4
  th Queue
5
5
  th Class
6
6
  th Arguments
7
7
  th Started
8
- - workers.each do |(worker, msg)|
8
+ - workers.each_with_index do |(worker, msg), index|
9
9
  tr
10
10
  td= worker
11
- td= msg['queue']
11
+ td
12
+ a href="queues/#{msg['queue']}" = msg['queue']
12
13
  td= msg['payload']['class']
13
- td= msg['payload']['args'].inspect[0..100]
14
+ td
15
+ - if msg['payload']['args'].to_s.size > 100
16
+ = msg['payload']['args'].inspect[0..100] + "... "
17
+ button data-toggle="collapse" data-target="#worker_#{index}" class="btn btn-mini" Show All
18
+ .collapse[id="worker_#{index}" style="max-width: 750px;"]= msg['payload']['args']
19
+ - else
20
+ = msg['payload']['args']
14
21
  td== relative_time(msg['run_at'].is_a?(Numeric) ? Time.at(msg['run_at']) : Time.parse(msg['run_at']))
@@ -1,11 +1,10 @@
1
- == slim :_summary
2
-
3
- .actions
4
- form.pull-left action="#{root_path}reset" method="post"
5
- button.btn.btn-small type="submit" title="If you kill -9 Sidekiq, this table can fill up with old data." Clear worker list
6
- .pull-right
7
- span.poll-status
8
- a.btn.btn-small name='poll' href='#{{root_path}}poll' Live Poll
1
+ .row.header
2
+ .span7
3
+ h3 Workers
9
4
 
10
5
  == slim :_workers
11
-
6
+ - if workers.size > 0
7
+ .row
8
+ .span2.pull-right
9
+ form action="#{root_path}reset" method="post"
10
+ button.btn.btn-primary.btn-block type="submit" title="If you kill -9 Sidekiq, this table can fill up with old data." Clear Worker List
@@ -1,33 +1,41 @@
1
1
  doctype html
2
2
  html
3
3
  head
4
+ link href='#{{root_path}}assets/vendors.css' media='screen' rel='stylesheet' type='text/css'
4
5
  link href='#{{root_path}}assets/application.css' media='screen' rel='stylesheet' type='text/css'
5
6
  title= Sidekiq::NAME
6
- body
7
- .navbar.navbar-fixed-top.navbar-inverse
7
+ body.admin
8
+ .navbar.navbar-fixed-top
9
+ ==slim :_nav
10
+ .navbar.navbar-fixed-bottom.navbar-inverse
8
11
  .navbar-inner
9
12
  .container
10
- a.btn.btn-navbar data-toggle="collapse" data-target=".nav-collapse"
11
- span.icon-bar
12
- span.icon-bar
13
- span.icon-bar
14
- a.brand href='#{{root_path}}'
15
- = Sidekiq::NAME
16
- div.nav-collapse
13
+ .nav-collapse
17
14
  ul.nav
18
15
  li
19
- a href='#{{root_path}}' Home
20
- - tabs.each do |tab|
21
- li
22
- a href='#{{root_path}}#{{tab.downcase}}': #{tab}
23
-
24
- ul.nav.pull-right
16
+ p.navbar-text style="color:white;" Sidekiq v#{Sidekiq::VERSION}
25
17
  li
26
- a Redis: #{location}
18
+ p.navbar-text Redis: #{location}
27
19
  li
28
- a #{Time.now.utc}
20
+ p.navbar-text Time: #{Time.now.utc.strftime('%H:%M:%S UTC')}
21
+
22
+
23
+ #page
24
+ .container
25
+ .row
26
+ .span2.summary_bar
27
+ h4
28
+ span.title Status
29
+ == slim :_status
30
+ == slim :_summary
31
+ .row
32
+ .span2
33
+ a#live-poll.btn.btn-block.btn-primary name='poll' href='#{{root_path}}poll' Live Poll
34
+ .span2.poll-status
35
+ span.text
36
+ span.time
29
37
 
30
- .container
31
- == yield
38
+ .span10
39
+ == yield
32
40
 
33
41
  script type="text/javascript" src="#{{root_path}}assets/application.js"
@@ -1,3 +1,4 @@
1
1
  div
2
2
  == slim :_summary
3
3
  == slim :_workers
4
+ == slim :_status
@@ -1,15 +1,28 @@
1
- header
2
- h1 Current messages in #{@name}
1
+ header.row
2
+ .span5
3
+ h3
4
+ | Current messages in
5
+ span.title #{@name}
6
+ .span4
7
+ == slim :_paging, :locals => { :url => "#{root_path}queues/#{@name}" }
3
8
 
4
- == slim :_paging, :locals => { :url => "#{root_path}queues/#{@name}" }
5
-
6
- table class="table table-striped table-bordered"
7
- tr
9
+ table class="queue table table-hover table-bordered table-striped"
10
+ thead
8
11
  th Class
9
12
  th Arguments
10
- - @messages.each do |msg|
13
+ th
14
+ - @messages.each_with_index do |msg, index|
11
15
  tr
12
16
  td= msg['class']
13
- td= msg['args'].inspect[0..100]
14
-
17
+ td
18
+ - if msg['args'] and msg['args'].to_s.size > 100
19
+ = msg['args'].inspect[0..100] + "... "
20
+ button data-toggle="collapse" data-target="#worker_#{index}" class="btn btn-mini" Show All
21
+ .collapse[id="worker_#{index}"]= msg['args']
22
+ - else
23
+ = msg['args']
24
+ td
25
+ form action="#{root_path}queues/#{@name}/delete" method="post"
26
+ input name="key_val" value="#{msg.to_json}" type="hidden"
27
+ input.btn.btn-danger.btn-mini type="submit" name="delete" value="Delete" data-confirm="Are you sure you want to delete this job?"
15
28
  == slim :_paging, :locals => { :url => "#{root_path}queues/#{@name}" }
@@ -1,19 +1,19 @@
1
- h1 Queues
1
+ h3 Queues
2
2
 
3
3
  - if @queues.size > 0
4
- table class="table table-striped table-bordered"
5
- tr
4
+ table class="queues table table-hover table-bordered table-striped table-white"
5
+ thead
6
6
  th Queue
7
7
  th Size
8
- th
8
+ th Actions
9
9
  - queues.each do |(queue, size)|
10
10
  tr
11
11
  td
12
12
  a href="#{root_path}queues/#{queue}" #{queue}
13
13
  td= number_with_delimiter(size)
14
- td
14
+ td width="20%"
15
15
  form action="#{root_path}queues/#{queue}" method="post"
16
- input.btn.btn-danger type="submit" name="delete" value="Delete" data-confirm="Are you sure you want to delete the #{queue} queue?"
16
+ input.btn.btn-danger.btn-small type="submit" name="delete" value="Delete" data-confirm="Are you sure you want to delete the #{queue} queue?"
17
17
  - else
18
18
  p No queues found.
19
- a href="#{root_path}" Back
19
+ a href="#{root_path}" Back
@@ -1,15 +1,19 @@
1
- h1 Retries
1
+ header.row
2
+ .span5
3
+ h3 Retries
4
+ .span4
5
+ - if @retries.size > 0
6
+ == slim :_paging, :locals => { :url => "#{root_path}retries" }
2
7
 
3
8
  - if @retries.size > 0
4
- == slim :_paging, :locals => { :url => "#{root_path}retries" }
5
9
 
6
10
  form action="#{root_path}retries" method="post"
7
- table class="table table-striped table-bordered"
11
+ table class="table table-striped table-bordered table-white"
8
12
  tr
9
- th
13
+ th width="20px"
10
14
  input type="checkbox" class="check_all"
11
- th Next Retry
12
- th Retry Count
15
+ th width="25%" Next Retry
16
+ th width="11%" Retry count
13
17
  th Queue
14
18
  th Worker
15
19
  th Args
@@ -24,8 +28,7 @@ h1 Retries
24
28
  a href="#{root_path}queues/#{msg['queue']}" #{msg['queue']}
25
29
  td= msg['class']
26
30
  td= display_args(msg['args'])
27
- input.btn.btn-primary type="submit" name="retry" value="Retry Now"
28
- input.btn.btn-danger type="submit" name="delete" value="Delete"
31
+ input.btn.btn-danger.btn-small.pull-right type="submit" name="delete" value="Delete"
32
+ input.btn.btn-primary.btn-small.pull-right type="submit" name="retry" value="Retry Now"
29
33
  - else
30
- p No retries found.
31
- a href="#{root_path}" Back
34
+ .alert.alert-success No retries were found