reqless 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +8 -0
  3. data/README.md +648 -0
  4. data/Rakefile +117 -0
  5. data/bin/docker-build-and-test +22 -0
  6. data/exe/reqless-web +11 -0
  7. data/lib/reqless/config.rb +31 -0
  8. data/lib/reqless/failure_formatter.rb +43 -0
  9. data/lib/reqless/job.rb +496 -0
  10. data/lib/reqless/job_reservers/ordered.rb +29 -0
  11. data/lib/reqless/job_reservers/round_robin.rb +46 -0
  12. data/lib/reqless/job_reservers/shuffled_round_robin.rb +21 -0
  13. data/lib/reqless/lua/reqless-lib.lua +2965 -0
  14. data/lib/reqless/lua/reqless.lua +2545 -0
  15. data/lib/reqless/lua_script.rb +90 -0
  16. data/lib/reqless/middleware/requeue_exceptions.rb +94 -0
  17. data/lib/reqless/middleware/retry_exceptions.rb +72 -0
  18. data/lib/reqless/middleware/sentry.rb +66 -0
  19. data/lib/reqless/middleware/timeout.rb +63 -0
  20. data/lib/reqless/queue.rb +189 -0
  21. data/lib/reqless/queue_priority_pattern.rb +16 -0
  22. data/lib/reqless/server/static/css/bootstrap-responsive.css +686 -0
  23. data/lib/reqless/server/static/css/bootstrap-responsive.min.css +12 -0
  24. data/lib/reqless/server/static/css/bootstrap.css +3991 -0
  25. data/lib/reqless/server/static/css/bootstrap.min.css +689 -0
  26. data/lib/reqless/server/static/css/codemirror.css +112 -0
  27. data/lib/reqless/server/static/css/docs.css +839 -0
  28. data/lib/reqless/server/static/css/jquery.noty.css +105 -0
  29. data/lib/reqless/server/static/css/noty_theme_twitter.css +137 -0
  30. data/lib/reqless/server/static/css/style.css +200 -0
  31. data/lib/reqless/server/static/favicon.ico +0 -0
  32. data/lib/reqless/server/static/img/glyphicons-halflings-white.png +0 -0
  33. data/lib/reqless/server/static/img/glyphicons-halflings.png +0 -0
  34. data/lib/reqless/server/static/js/bootstrap-alert.js +94 -0
  35. data/lib/reqless/server/static/js/bootstrap-scrollspy.js +125 -0
  36. data/lib/reqless/server/static/js/bootstrap-tab.js +130 -0
  37. data/lib/reqless/server/static/js/bootstrap-tooltip.js +270 -0
  38. data/lib/reqless/server/static/js/bootstrap-typeahead.js +285 -0
  39. data/lib/reqless/server/static/js/bootstrap.js +1726 -0
  40. data/lib/reqless/server/static/js/bootstrap.min.js +6 -0
  41. data/lib/reqless/server/static/js/codemirror.js +2972 -0
  42. data/lib/reqless/server/static/js/jquery.noty.js +220 -0
  43. data/lib/reqless/server/static/js/mode/javascript.js +360 -0
  44. data/lib/reqless/server/static/js/theme/cobalt.css +18 -0
  45. data/lib/reqless/server/static/js/theme/eclipse.css +25 -0
  46. data/lib/reqless/server/static/js/theme/elegant.css +10 -0
  47. data/lib/reqless/server/static/js/theme/lesser-dark.css +45 -0
  48. data/lib/reqless/server/static/js/theme/monokai.css +28 -0
  49. data/lib/reqless/server/static/js/theme/neat.css +9 -0
  50. data/lib/reqless/server/static/js/theme/night.css +21 -0
  51. data/lib/reqless/server/static/js/theme/rubyblue.css +21 -0
  52. data/lib/reqless/server/static/js/theme/xq-dark.css +46 -0
  53. data/lib/reqless/server/views/_job.erb +259 -0
  54. data/lib/reqless/server/views/_job_list.erb +8 -0
  55. data/lib/reqless/server/views/_pagination.erb +7 -0
  56. data/lib/reqless/server/views/about.erb +130 -0
  57. data/lib/reqless/server/views/completed.erb +11 -0
  58. data/lib/reqless/server/views/config.erb +14 -0
  59. data/lib/reqless/server/views/failed.erb +48 -0
  60. data/lib/reqless/server/views/failed_type.erb +18 -0
  61. data/lib/reqless/server/views/job.erb +17 -0
  62. data/lib/reqless/server/views/layout.erb +451 -0
  63. data/lib/reqless/server/views/overview.erb +137 -0
  64. data/lib/reqless/server/views/queue.erb +125 -0
  65. data/lib/reqless/server/views/queues.erb +45 -0
  66. data/lib/reqless/server/views/tag.erb +6 -0
  67. data/lib/reqless/server/views/throttles.erb +38 -0
  68. data/lib/reqless/server/views/track.erb +75 -0
  69. data/lib/reqless/server/views/worker.erb +34 -0
  70. data/lib/reqless/server/views/workers.erb +14 -0
  71. data/lib/reqless/server.rb +549 -0
  72. data/lib/reqless/subscriber.rb +74 -0
  73. data/lib/reqless/test_helpers/worker_helpers.rb +55 -0
  74. data/lib/reqless/throttle.rb +57 -0
  75. data/lib/reqless/version.rb +5 -0
  76. data/lib/reqless/worker/base.rb +237 -0
  77. data/lib/reqless/worker/forking.rb +215 -0
  78. data/lib/reqless/worker/serial.rb +41 -0
  79. data/lib/reqless/worker.rb +5 -0
  80. data/lib/reqless.rb +309 -0
  81. metadata +399 -0
@@ -0,0 +1,125 @@
1
+ <script type="text/javascript" src="https://www.google.com/jsapi"></script>
2
+ <script type="text/javascript">
3
+ google.load("visualization", "1", {packages:["corechart"]});
4
+ google.setOnLoadCallback(drawCharts);
5
+
6
+ function drawCharts() {
7
+ drawChart(<%= JSON.generate(stats['wait']['histogram']) %>, 'wait-chart', 'Jobs / Minute');
8
+ drawChart(<%= JSON.generate(stats['run' ]['histogram']) %>, 'run-chart' , 'Jobs / Minute');
9
+ }
10
+
11
+ function drawChart(d, id, title) {
12
+ var data = new google.visualization.DataTable();
13
+ data.addColumn('string', 'Time');
14
+ data.addColumn('number', title);
15
+
16
+ var _data = [];
17
+ for (var i = 0; i < 60; ++i) {
18
+ _data.push([i + ' seconds', d[i] * 60]);
19
+ }
20
+ for (var i = 1; i < 60; ++i) {
21
+ _data.push([i + ' minutes', d[59 + i]]);
22
+ }
23
+ for (var i = 1; i < 24; ++i) {
24
+ _data.push([i + ' hours', d[118 + i] / 60]);
25
+ }
26
+ for (var i = 1; i < 7; ++i) {
27
+ _data.push([i + ' days', d[141 + i] / 1440]);
28
+ }
29
+ data.addRows(_data);
30
+
31
+ var options = {
32
+ legend: {position: 'none'},
33
+ chartArea: { width:"80%", height:"80%" }
34
+ };
35
+
36
+ var chart = new google.visualization.SteppedAreaChart(document.getElementById(id));
37
+ chart.draw(data, options);
38
+ }
39
+ </script>
40
+
41
+ <div class="subnav subnav-fixed">
42
+ <ul class="nav nav-pills">
43
+ <li class="<%= tab == 'stats' ? 'active' : '' %>"><a href="<%= u "/queues/#{CGI::escape(queue['name'])}/stats" %>">Stats</a></li>
44
+ <li class="<%= tab == 'running' ? 'active' : '' %>"><a href="<%= u "/queues/#{CGI::escape(queue['name'])}/running" %>">Running</a></li>
45
+ <li class="<%= tab == 'waiting' ? 'active' : '' %>"><a href="<%= u "/queues/#{CGI::escape(queue['name'])}/waiting" %>">Waiting</a></li>
46
+ <li class="<%= tab == 'throttled' ? 'active' : '' %>"><a href="<%= u "/queues/#{CGI::escape(queue['name'])}/throttled" %>">Throttled</a></li>
47
+ <li class="<%= tab == 'scheduled' ? 'active' : '' %>"><a href="<%= u "/queues/#{CGI::escape(queue['name'])}/scheduled" %>">Scheduled</a></li>
48
+ <li class="<%= tab == 'stalled' ? 'active' : '' %>"><a href="<%= u "/queues/#{CGI::escape(queue['name'])}/stalled" %>">Stalled</a></li>
49
+ <li class="<%= tab == 'depends' ? 'active' : '' %>"><a href="<%= u "/queues/#{CGI::escape(queue['name'])}/depends" %>">Depends</a></li>
50
+ <li class="<%= tab == 'recurring' ? 'active' : '' %>"><a href="<%= u "/queues/#{CGI::escape(queue['name'])}/recurring" %>">Recurring</a></li>
51
+ </ul>
52
+ </div>
53
+
54
+ <div id="alerts" style="margin-top: 40px"></div>
55
+
56
+ <div class="row">
57
+ <div class="span8">
58
+ <h2><a href="<%= u "/queues/#{CGI::escape(queue['name'])}" %>"><%= queue['name'] %></a> |
59
+ <%= queue['running'] %> /
60
+ <%= queue['waiting'] %> /
61
+ <%= queue['throttled'] %> /
62
+ <%= queue['scheduled'] %> /
63
+ <%= queue['stalled'] %> /
64
+ <%= queue['depends'] %> <small>(running / waiting / throttled / scheduled / stalled / depends)</small>
65
+ </h2>
66
+ </div>
67
+
68
+ <div class="span4">
69
+ <div style="float:right">
70
+ <h2>
71
+ <%= stats['failed'] %> /
72
+ <%= stats['failures'] %> /
73
+ <%= stats['retries'] %> <small>(failed / failures / retries)</small>
74
+ </h2>
75
+ </div>
76
+ </div>
77
+ </div>
78
+
79
+ <% if ['running', 'waiting', 'throttled', 'scheduled', 'stalled', 'depends', 'recurring'].include?(tab) %>
80
+ <hr/>
81
+ <%= erb :_job_list, :locals => { :jobs => jobs, :queues => queues } %>
82
+ <% else %>
83
+ <div class="row" style="margin-top: 15px">
84
+ <div class="span6">
85
+ <div class="well">
86
+ <div class="row">
87
+ <div class="span12">
88
+ <h3>Waiting</h3>
89
+ </div>
90
+ </div>
91
+ <div class="row">
92
+ <div class="span12">
93
+ <h3>
94
+ <%= stats['wait']['count'] %> /
95
+ <%= sprintf('%10.3f', stats['wait']['mean']) %> /
96
+ <%= sprintf('%10.3f', stats['wait']['std']) %> <small>Total / Mean / Std. Deviation</small>
97
+ </h3>
98
+ </div>
99
+ </div>
100
+ <div id="wait-chart" class="queue-stats-time-histogram-wait" style="height: 500px"></div>
101
+ </div>
102
+ </div>
103
+
104
+ <div class="span6">
105
+ <div class="well">
106
+ <div class="row">
107
+ <div class="span12">
108
+ <h3>Running</h3>
109
+ </div>
110
+ </div>
111
+ <div class="row">
112
+ <div class="span12">
113
+ <h3>
114
+ <%= stats['run']['count'] %> /
115
+ <%= sprintf('%10.3f', stats['run']['mean']) %> /
116
+ <%= sprintf('%10.3f', stats['run']['std']) %> <small>Total / Mean / Std. Deviation</small>
117
+ </h3>
118
+ </div>
119
+ </div>
120
+
121
+ <div id="run-chart" class="queue-stats-time-histogram-run" style="height: 500px"></div>
122
+ </div>
123
+ </div>
124
+ </div>
125
+ <% end %>
@@ -0,0 +1,45 @@
1
+ <% if queues.empty? %>
2
+ <div class="page-header">
3
+ <h1>No Queues <small>I wish I had some queues :-/</small></h1>
4
+ </div>
5
+ <% else %>
6
+ <div class="page-header">
7
+ <h1>Queues <small>And their job counts</small></h1>
8
+ </div>
9
+
10
+ <% queues.each do |queue| %>
11
+ <div class="row">
12
+ <div class="span4">
13
+ <h3>
14
+ <% if queue['paused'] %>
15
+ <button
16
+ id="<%= queue['name'] %>-pause"
17
+ title="Unpause"
18
+ class="btn btn-success"
19
+ onclick="unpause('<%= queue['name'] %>')"><i class="icon-play"></i>
20
+ </button>
21
+ <% else %>
22
+ <button
23
+ id="<%= queue['name'] %>-pause"
24
+ title="Pause"
25
+ class="btn btn-warning"
26
+ onclick="pause('<%= queue['name'] %>')"><i class="icon-pause"></i>
27
+ </button>
28
+ <% end %>
29
+ <a href="<%= u "/queues/#{CGI::escape(queue['name'])}" %>"><%= queue['name'] %></a>
30
+ </h3>
31
+ </div>
32
+ <div class="span8">
33
+ <h3> |
34
+ <%= queue['running'] %> /
35
+ <%= queue['waiting'] %> /
36
+ <%= queue['throttled'] %> /
37
+ <%= queue['scheduled'] %> /
38
+ <%= queue['stalled'] %> /
39
+ <%= queue['depends'] %> /
40
+ <%= queue['recurring'] %> <small>(running / waiting / throttled / scheduled / stalled / depends / recurring)</small>
41
+ </h3>
42
+ </div>
43
+ </div>
44
+ <% end %>
45
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <div class="page-header">
2
+ <h2>Jobs tagged '<%= tag %>'</h2>
3
+ </div>
4
+
5
+ <%= erb :_job_list, :locals => { :jobs => jobs, :queues => queues } %>
6
+
@@ -0,0 +1,38 @@
1
+ <% if throttles.empty? %>
2
+ <div class="page-header">
3
+ <h1>No Queues To Throttle <small>What a fine predicament to be in...</small></h1>
4
+ </div>
5
+ <% else %>
6
+ <div class="page-header">
7
+ <h1>Throttles <small>for queue concurrency</small></h1>
8
+ </div>
9
+
10
+ <table class="table">
11
+ <thead>
12
+ <tr>
13
+ <th> Queue </th>
14
+ <th> Maximum </th>
15
+ <th> TTL (sets expiration) </th>
16
+ <th> Reset </th>
17
+ </tr>
18
+ </thead>
19
+ <tbody>
20
+ <% throttles.each do |throttle| %>
21
+ <tr class="tracked-row">
22
+ <td class="large-text"><%= throttle.id %></td>
23
+ <td>
24
+ <input class="span1 <%= throttle.id.gsub(':', '-') %>-maximum" type="text" placeholder="<%= throttle.maximum %>" onchange="update_throttle('<%= throttle.id %>', $(this).val())"></input>
25
+ </td>
26
+ <td>
27
+ <input class="span1 <%= throttle.id.gsub(':', '-') %>-expiration" type="text" placeholder="<%= throttle.ttl %>" onchange="expire_throttle('<%= throttle.id %>', $(this).val())"></input>
28
+ </td>
29
+ <td>
30
+ <button title="delete" class="btn btn-danger" onclick="confirmation(this, 'Delete?', function() { delete_throttle('<%= throttle.id %>', fade) })">
31
+ <i class="icon-remove"></i>
32
+ </button>
33
+ </td>
34
+ </tr>
35
+ <% end %>
36
+ </tbody>
37
+ </table>
38
+ <% end %>
@@ -0,0 +1,75 @@
1
+ <script>
2
+ var fade = function(jid, type) {
3
+ if (type == 'cancel' || type == 'untrack') {
4
+ $('#job-' + jid).slideUp();
5
+ }
6
+ }
7
+ </script>
8
+
9
+ <div class="subnav subnav-fixed">
10
+ <ul class="nav nav-pills">
11
+ <li class="active"><a href="#all" data-toggle="tab">All (<%= tracked['jobs'].length %>)</a></li>
12
+ <li><a href="#running" data-toggle="tab">Running (<%= tracked['jobs'].select { |job| job.state == 'running' }.length %>)</a></li>
13
+ <li><a href="#waiting" data-toggle="tab">Waiting (<%= tracked['jobs'].select { |job| job.state == 'waiting' }.length %>)</a></li>
14
+ <li><a href="#throttled" data-toggle="tab">Throttled (<%= tracked['jobs'].select { |job| job.state == 'throttled'}.length %>)</a></li>
15
+ <li><a href="#scheduled" data-toggle="tab">Scheduled (<%= tracked['jobs'].select { |job| job.state == 'scheduled' }.length %>)</a></li>
16
+ <li><a href="#stalled" data-toggle="tab">Stalled (<%= tracked['jobs'].select { |job| job.state == 'stalled' }.length %>)</a></li>
17
+ <li><a href="#completed" data-toggle="tab">Completed (<%= tracked['jobs'].select { |job| job.state == 'complete' }.length %>)</a></li>
18
+ <li><a href="#failed" data-toggle="tab">Failed (<%= tracked['jobs'].select { |job| job.state == 'failed' }.length %>)</a></li>
19
+ <li><a href="#depends" data-toggle="tab">Depends (<%= tracked['jobs'].select { |job| job.state == 'depends' }.length %>)</a></li>
20
+ </ul>
21
+ </div>
22
+
23
+ <div id="alerts" style="margin-top: 40px"></div>
24
+
25
+ <div class="page-header">
26
+ <h1>Tracked Jobs <small>These are all the jobs you're tracking</h1>
27
+ </div>
28
+
29
+ <div class="tab-content">
30
+ <div class="tab-pane active" id="all">
31
+ <% tracked['jobs'].each do |job| %>
32
+ <%= erb :_job, :layout => false, :locals => { :job => job, :queues => queues } %>
33
+ <% end %>
34
+ </div>
35
+ <div class="tab-pane" id="running">
36
+ <% tracked['jobs'].select { |job| job.state == 'running' }.each do |job| %>
37
+ <%= erb :_job, :layout => false, :locals => { :job => job, :queues => queues } %>
38
+ <% end %>
39
+ </div>
40
+ <div class="tab-pane" id="waiting">
41
+ <% tracked['jobs'].select { |job| job.state == 'waiting' }.each do |job| %>
42
+ <%= erb :_job, :layout => false, :locals => { :job => job, :queues => queues } %>
43
+ <% end %>
44
+ </div>
45
+ <div class="tab-pane" id="throttled">
46
+ <% tracked['jobs'].select { |job| job.state == 'throttled' }.each do |job| %>
47
+ <%= erb :_job, :layout => false, :locals => { :job => job, :queues => queues } %>
48
+ <% end %>
49
+ </div>
50
+ <div class="tab-pane" id="scheduled">
51
+ <% tracked['jobs'].select { |job| job.state == 'scheduled' }.each do |job| %>
52
+ <%= erb :_job, :layout => false, :locals => { :job => job, :queues => queues } %>
53
+ <% end %>
54
+ </div>
55
+ <div class="tab-pane" id="stalled">
56
+ <% tracked['jobs'].select { |job| job.state == 'stalled' }.each do |job| %>
57
+ <%= erb :_job, :layout => false, :locals => { :job => job, :queues => queues } %>
58
+ <% end %>
59
+ </div>
60
+ <div class="tab-pane" id="completed">
61
+ <% tracked['jobs'].select { |job| job.state == 'complete' }.each do |job| %>
62
+ <%= erb :_job, :layout => false, :locals => { :job => job, :queues => queues } %>
63
+ <% end %>
64
+ </div>
65
+ <div class="tab-pane" id="failed">
66
+ <% tracked['jobs'].select { |job| job.state == 'failed' }.each do |job| %>
67
+ <%= erb :_job, :layout => false, :locals => { :job => job, :queues => queues } %>
68
+ <% end %>
69
+ </div>
70
+ <div class="tab-pane" id="depends">
71
+ <% tracked['jobs'].select { |job| job.state == 'depends' }.each do |job| %>
72
+ <%= erb :_job, :layout => false, :locals => { :job => job, :queues => queues } %>
73
+ <% end %>
74
+ </div>
75
+ </div>
@@ -0,0 +1,34 @@
1
+ <div class="subnav subnav-fixed">
2
+ <ul class="nav nav-pills">
3
+ <li><a href="#Running">Running</a></li>
4
+ <li><a href="#Stalled">Stalled</a></li>
5
+ </ul>
6
+ </div>
7
+
8
+ <div id="alerts" style="margin-top: 40px"></div>
9
+
10
+ <% if worker['jobs'].length > 0 %>
11
+ <div class="page-header">
12
+ <h1><%= worker['name'] %> <small>Running Jobs</small></h1>
13
+ </div>
14
+
15
+ <% worker['jobs'].each do |job| %>
16
+ <%= erb :_job, :layout => false, :locals => { :job => job, :queues => queues } %>
17
+ <% end %>
18
+ <% end %>
19
+
20
+ <% if worker['stalled'].length > 0 %>
21
+ <div class="page-header">
22
+ <h1><%= worker['name'] %> <small>Stalled Jobs</small></h1>
23
+ </div>
24
+
25
+ <% worker['stalled'].each do |job| %>
26
+ <%= erb :_job, :layout => false, :locals => { :job => job, :queues => queues } %>
27
+ <% end %>
28
+ <% end %>
29
+
30
+ <% if worker['stalled'].length + worker['jobs'].length == 0 %>
31
+ <div class="page-header">
32
+ <h1><%= worker['name'] %> <small>Isn't Doing Anything</small></h1>
33
+ </div>
34
+ <% end %>
@@ -0,0 +1,14 @@
1
+ <div class="page-header">
2
+ <h1>Current Workers <small>And their job counts</small></h1>
3
+ </div>
4
+
5
+ <% workers.each do |worker| %>
6
+ <div class="row">
7
+ <div class="span4">
8
+ <h3><a href="<%= u "/workers/#{worker['name']}" %>"><%= worker['name'] %></a></h3>
9
+ </div>
10
+ <div class="span8">
11
+ <h3>| <%= worker['jobs'] %> / <%= worker['stalled'] %> <small>Running / Stalled</small></h3>
12
+ </div>
13
+ </div>
14
+ <% end %>