sidekiq 6.5.12 → 7.0.0.beta1

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 (94) hide show
  1. checksums.yaml +4 -4
  2. data/Changes.md +5 -24
  3. data/README.md +13 -12
  4. data/bin/sidekiq +3 -8
  5. data/bin/sidekiqload +14 -23
  6. data/lib/sidekiq/api.rb +51 -127
  7. data/lib/sidekiq/capsule.rb +110 -0
  8. data/lib/sidekiq/cli.rb +44 -59
  9. data/lib/sidekiq/client.rb +30 -17
  10. data/lib/sidekiq/component.rb +1 -0
  11. data/lib/sidekiq/config.rb +270 -0
  12. data/lib/sidekiq/deploy.rb +62 -0
  13. data/lib/sidekiq/embedded.rb +61 -0
  14. data/lib/sidekiq/fetch.rb +10 -11
  15. data/lib/sidekiq/job.rb +375 -10
  16. data/lib/sidekiq/job_logger.rb +1 -1
  17. data/lib/sidekiq/job_retry.rb +8 -8
  18. data/lib/sidekiq/job_util.rb +4 -4
  19. data/lib/sidekiq/launcher.rb +36 -46
  20. data/lib/sidekiq/logger.rb +1 -26
  21. data/lib/sidekiq/manager.rb +9 -11
  22. data/lib/sidekiq/metrics/query.rb +3 -3
  23. data/lib/sidekiq/metrics/shared.rb +4 -3
  24. data/lib/sidekiq/metrics/tracking.rb +18 -18
  25. data/lib/sidekiq/middleware/chain.rb +7 -9
  26. data/lib/sidekiq/middleware/current_attributes.rb +3 -8
  27. data/lib/sidekiq/monitor.rb +1 -1
  28. data/lib/sidekiq/paginator.rb +1 -9
  29. data/lib/sidekiq/pool.rb +7 -0
  30. data/lib/sidekiq/processor.rb +17 -26
  31. data/lib/sidekiq/rails.rb +11 -10
  32. data/lib/sidekiq/redis_client_adapter.rb +9 -45
  33. data/lib/sidekiq/redis_connection.rb +11 -111
  34. data/lib/sidekiq/scheduled.rb +19 -20
  35. data/lib/sidekiq/testing.rb +4 -32
  36. data/lib/sidekiq/transaction_aware_client.rb +4 -5
  37. data/lib/sidekiq/version.rb +1 -1
  38. data/lib/sidekiq/web/application.rb +1 -4
  39. data/lib/sidekiq/web/csrf_protection.rb +1 -1
  40. data/lib/sidekiq/web/helpers.rb +21 -22
  41. data/lib/sidekiq/web.rb +2 -17
  42. data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
  43. data/lib/sidekiq.rb +52 -274
  44. data/sidekiq.gemspec +29 -5
  45. data/web/assets/javascripts/application.js +0 -1
  46. data/web/assets/javascripts/base-charts.js +106 -0
  47. data/web/assets/javascripts/dashboard-charts.js +166 -0
  48. data/web/assets/javascripts/dashboard.js +3 -223
  49. data/web/assets/javascripts/metrics.js +90 -116
  50. data/web/assets/stylesheets/application-rtl.css +2 -91
  51. data/web/assets/stylesheets/application.css +21 -296
  52. data/web/locales/ar.yml +70 -70
  53. data/web/locales/cs.yml +62 -62
  54. data/web/locales/da.yml +52 -52
  55. data/web/locales/de.yml +65 -65
  56. data/web/locales/el.yml +2 -7
  57. data/web/locales/en.yml +76 -70
  58. data/web/locales/es.yml +68 -68
  59. data/web/locales/fa.yml +65 -65
  60. data/web/locales/fr.yml +67 -67
  61. data/web/locales/he.yml +65 -64
  62. data/web/locales/hi.yml +59 -59
  63. data/web/locales/it.yml +53 -53
  64. data/web/locales/ja.yml +64 -68
  65. data/web/locales/ko.yml +52 -52
  66. data/web/locales/lt.yml +66 -66
  67. data/web/locales/nb.yml +61 -61
  68. data/web/locales/nl.yml +52 -52
  69. data/web/locales/pl.yml +45 -45
  70. data/web/locales/pt-br.yml +59 -69
  71. data/web/locales/pt.yml +51 -51
  72. data/web/locales/ru.yml +67 -66
  73. data/web/locales/sv.yml +53 -53
  74. data/web/locales/ta.yml +60 -60
  75. data/web/locales/uk.yml +62 -61
  76. data/web/locales/ur.yml +64 -64
  77. data/web/locales/vi.yml +67 -67
  78. data/web/locales/zh-cn.yml +1 -0
  79. data/web/locales/zh-tw.yml +10 -1
  80. data/web/views/_footer.erb +5 -2
  81. data/web/views/busy.erb +1 -6
  82. data/web/views/dashboard.erb +36 -5
  83. data/web/views/metrics.erb +30 -19
  84. data/web/views/metrics_for_job.erb +16 -34
  85. metadata +60 -37
  86. data/lib/sidekiq/delay.rb +0 -43
  87. data/lib/sidekiq/extensions/action_mailer.rb +0 -48
  88. data/lib/sidekiq/extensions/active_record.rb +0 -43
  89. data/lib/sidekiq/extensions/class_methods.rb +0 -43
  90. data/lib/sidekiq/extensions/generic_proxy.rb +0 -33
  91. data/lib/sidekiq/metrics/deploy.rb +0 -47
  92. data/lib/sidekiq/worker.rb +0 -370
  93. data/web/assets/javascripts/graph.js +0 -16
  94. /data/{LICENSE → LICENSE.txt} +0 -0
@@ -0,0 +1,166 @@
1
+ class DashboardChart extends BaseChart {
2
+ constructor(el, options) {
3
+ super(el, { ...options, chartType: "line" });
4
+ this.init();
5
+ }
6
+
7
+ get data() {
8
+ return [this.options.processed, this.options.failed];
9
+ }
10
+
11
+ get datasets() {
12
+ return [
13
+ {
14
+ label: this.options.processedLabel,
15
+ data: this.data[0],
16
+ borderColor: this.colors.success,
17
+ backgroundColor: this.colors.success,
18
+ borderWidth: 2,
19
+ pointRadius: 2,
20
+ },
21
+ {
22
+ label: this.options.failedLabel,
23
+ data: this.data[1],
24
+ borderColor: this.colors.failure,
25
+ backgroundColor: this.colors.failure,
26
+ borderWidth: 2,
27
+ pointRadius: 2,
28
+ },
29
+ ];
30
+ }
31
+
32
+ get chartOptions() {
33
+ return {
34
+ ...super.chartOptions,
35
+ aspectRatio: 4,
36
+ scales: {
37
+ ...super.chartOptions.scales,
38
+ x: {
39
+ ...super.chartOptions.scales.x,
40
+ ticks: {
41
+ ...super.chartOptions.scales.x.ticks,
42
+ callback: function (value, index, ticks) {
43
+ // Remove the year from the date string
44
+ return this.getLabelForValue(value).split("-").slice(1).join("-");
45
+ },
46
+ },
47
+ },
48
+ y: {
49
+ ...super.chartOptions.scales.y,
50
+ beginAtZero: true,
51
+ },
52
+ },
53
+ };
54
+ }
55
+ }
56
+
57
+ class RealtimeChart extends DashboardChart {
58
+ constructor(el, options) {
59
+ super(el, options);
60
+ this.delay = parseInt(localStorage.sidekiqTimeInterval) || 5000;
61
+ this.startPolling();
62
+ document.addEventListener("interval:update", this.handleUpdate.bind(this));
63
+ }
64
+
65
+ async startPolling() {
66
+ // Fetch initial values so we can show diffs moving forward
67
+ this.stats = await this.fetchStats();
68
+ this._interval = setInterval(this.poll.bind(this), this.delay);
69
+ }
70
+
71
+ async poll() {
72
+ const stats = await this.fetchStats();
73
+ const processed = stats.sidekiq.processed - this.stats.sidekiq.processed;
74
+ const failed = stats.sidekiq.failed - this.stats.sidekiq.failed;
75
+
76
+ this.chart.data.labels.shift();
77
+ this.chart.data.datasets[0].data.shift();
78
+ this.chart.data.datasets[1].data.shift();
79
+ this.chart.data.labels.push(new Date().toUTCString().split(" ")[4]);
80
+ this.chart.data.datasets[0].data.push(processed);
81
+ this.chart.data.datasets[1].data.push(failed);
82
+ this.chart.update();
83
+
84
+ updateStatsSummary(this.stats.sidekiq);
85
+ updateRedisStats(this.stats.redis);
86
+ updateFooterUTCTime(this.stats.server_utc_time);
87
+ pulseBeacon();
88
+
89
+ this.stats = stats;
90
+ }
91
+
92
+ async fetchStats() {
93
+ const response = await fetch(this.options.updateUrl);
94
+ return await response.json();
95
+ }
96
+
97
+ handleUpdate(e) {
98
+ this.delay = parseInt(e.detail);
99
+ clearInterval(this._interval);
100
+ this.startPolling();
101
+ }
102
+
103
+ registerLegend(el) {
104
+ this.legend = el;
105
+ }
106
+
107
+ renderLegend(dp) {
108
+ this.legend.innerHTML = `
109
+ <span>
110
+ <span class="swatch" style="background-color: ${dp[0].dataset.borderColor};"></span>
111
+ <span>${dp[0].dataset.label}: ${dp[0].formattedValue}</span>
112
+ </span>
113
+ <span>
114
+ <span class="swatch" style="background-color: ${dp[1].dataset.borderColor};"></span>
115
+ <span>${dp[1].dataset.label}: ${dp[1].formattedValue}</span>
116
+ </span>
117
+ <span class="time">${dp[0].label}</span>
118
+ `;
119
+ }
120
+
121
+ renderCursor(dp) {
122
+ if (this.cursorX != dp[0].label) {
123
+ this.cursorX = dp[0].label;
124
+ this.update()
125
+ }
126
+ }
127
+
128
+ get chartOptions() {
129
+ return {
130
+ ...super.chartOptions,
131
+ scales: {
132
+ ...super.chartOptions.scales,
133
+ x: {
134
+ ...super.chartOptions.scales.x,
135
+ display: false,
136
+ },
137
+ },
138
+ plugins: {
139
+ ...super.chartOptions.plugins,
140
+ tooltip: {
141
+ ...super.chartOptions.plugins.tooltip,
142
+ enabled: false,
143
+ external: (context) => {
144
+ const dp = context.tooltip.dataPoints;
145
+ if (dp && dp.length == 2 && this.legend) {
146
+ this.renderLegend(dp);
147
+ this.renderCursor(dp);
148
+ }
149
+ },
150
+ },
151
+ annotation: {
152
+ annotations: {
153
+ ...super.chartOptions.plugins.annotation.annotations,
154
+ cursor: this.cursorX && {
155
+ type: "line",
156
+ borderColor: "rgba(0, 0, 0, 0.3)",
157
+ xMin: this.cursorX,
158
+ xMax: this.cursorX,
159
+ borderWidth: 1,
160
+ },
161
+ },
162
+ },
163
+ },
164
+ };
165
+ }
166
+ }
@@ -1,188 +1,6 @@
1
1
  Sidekiq = {};
2
2
 
3
3
  var nf = new Intl.NumberFormat();
4
- var poller;
5
- var realtimeGraph = function(updatePath) {
6
- var timeInterval = parseInt(localStorage.sidekiqTimeInterval) || 5000;
7
- var graphElement = document.getElementById("realtime");
8
-
9
- var graph = new Rickshaw.Graph( {
10
- element: graphElement,
11
- width: responsiveWidth(),
12
- height: 200,
13
- renderer: 'line',
14
- interpolation: 'linear',
15
-
16
- series: new Rickshaw.Series.FixedDuration([{ name: graphElement.dataset.failedLabel, color: '#af0014' }, { name: graphElement.dataset.processedLabel, color: '#006f68' }], undefined, {
17
- timeInterval: timeInterval,
18
- maxDataPoints: 100,
19
- })
20
- });
21
-
22
- var y_axis = new Rickshaw.Graph.Axis.Y( {
23
- graph: graph,
24
- tickFormat: Rickshaw.Fixtures.Number.formatKMBT,
25
- ticksTreatment: 'glow'
26
- });
27
-
28
- graph.render();
29
-
30
- var legend = document.getElementById('realtime-legend');
31
- var Hover = Rickshaw.Class.create(Rickshaw.Graph.HoverDetail, {
32
- render: function(args) {
33
- legend.innerHTML = "";
34
-
35
- var timestamp = document.createElement('div');
36
- timestamp.className = 'timestamp';
37
- timestamp.innerHTML = args.formattedXValue;
38
- legend.appendChild(timestamp);
39
-
40
- args.detail.sort(function(a, b) { return a.order - b.order }).forEach( function(d) {
41
- var line = document.createElement('div');
42
- line.className = 'line';
43
-
44
- var swatch = document.createElement('div');
45
- swatch.className = 'swatch';
46
- swatch.style.backgroundColor = d.series.color;
47
-
48
- var label = document.createElement('div');
49
- label.className = 'tag';
50
- label.innerHTML = d.name + ": " + nf.format(Math.floor(d.formattedYValue));
51
-
52
- line.appendChild(swatch);
53
- line.appendChild(label);
54
- legend.appendChild(line);
55
-
56
- var dot = document.createElement('div');
57
- dot.className = 'dot';
58
- dot.style.top = graph.y(d.value.y0 + d.value.y) + 'px';
59
- dot.style.borderColor = d.series.color;
60
-
61
- this.element.appendChild(dot);
62
- dot.className = 'dot active';
63
- this.show();
64
- }, this );
65
- }
66
- });
67
- var hover = new Hover( { graph: graph } );
68
-
69
- var i = 0;
70
- poller = setInterval(function() {
71
- var url = document.getElementById("history").getAttribute("data-update-url");
72
-
73
- fetch(url).then(response => response.json()).then(data => {
74
- if (i === 0) {
75
- var processed = data.sidekiq.processed;
76
- var failed = data.sidekiq.failed;
77
- } else {
78
- var processed = data.sidekiq.processed - Sidekiq.processed;
79
- var failed = data.sidekiq.failed - Sidekiq.failed;
80
- }
81
-
82
- dataPoint = {};
83
- dataPoint[graphElement.dataset.failedLabel] = failed;
84
- dataPoint[graphElement.dataset.processedLabel] = processed;
85
-
86
- graph.series.addData(dataPoint);
87
- graph.render();
88
-
89
- Sidekiq.processed = data.sidekiq.processed;
90
- Sidekiq.failed = data.sidekiq.failed;
91
-
92
- updateStatsSummary(data.sidekiq);
93
- updateRedisStats(data.redis);
94
- updateFooterUTCTime(data.server_utc_time)
95
-
96
- pulseBeacon();
97
- });
98
-
99
- i++;
100
- }, timeInterval);
101
- }
102
-
103
- var historyGraph = function() {
104
- var h = document.getElementById("history");
105
- processed = createSeries(h.getAttribute("data-processed"));
106
- failed = createSeries(h.getAttribute("data-failed"));
107
-
108
- var graphElement = h;
109
- var graph = new Rickshaw.Graph( {
110
- element: graphElement,
111
- width: responsiveWidth(),
112
- height: 200,
113
- renderer: 'line',
114
- interpolation: 'linear',
115
- series: [
116
- {
117
- color: "#af0014",
118
- data: failed,
119
- name: graphElement.dataset.failedLabel
120
- }, {
121
- color: "#006f68",
122
- data: processed,
123
- name: graphElement.dataset.processedLabel
124
- }
125
- ]
126
- } );
127
- var x_axis = new Rickshaw.Graph.Axis.Time( { graph: graph } );
128
- var y_axis = new Rickshaw.Graph.Axis.Y({
129
- graph: graph,
130
- tickFormat: Rickshaw.Fixtures.Number.formatKMBT,
131
- ticksTreatment: 'glow'
132
- });
133
-
134
- graph.render();
135
-
136
- var legend = document.getElementById('history-legend');
137
- var Hover = Rickshaw.Class.create(Rickshaw.Graph.HoverDetail, {
138
- render: function(args) {
139
- legend.innerHTML = "";
140
-
141
- var timestamp = document.createElement('div');
142
- timestamp.className = 'timestamp';
143
- timestamp.innerHTML = args.formattedXValue;
144
- legend.appendChild(timestamp);
145
-
146
- args.detail.sort(function(a, b) { return a.order - b.order }).forEach( function(d) {
147
- var line = document.createElement('div');
148
- line.className = 'line';
149
-
150
- var swatch = document.createElement('div');
151
- swatch.className = 'swatch';
152
- swatch.style.backgroundColor = d.series.color;
153
-
154
- var label = document.createElement('div');
155
- label.className = 'tag';
156
- label.innerHTML = d.name + ": " + nf.format(Math.floor(d.formattedYValue));
157
-
158
- line.appendChild(swatch);
159
- line.appendChild(label);
160
- legend.appendChild(line);
161
-
162
- var dot = document.createElement('div');
163
- dot.className = 'dot';
164
- dot.style.top = graph.y(d.value.y0 + d.value.y) + 'px';
165
- dot.style.borderColor = d.series.color;
166
-
167
- this.element.appendChild(dot);
168
- dot.className = 'dot active';
169
- this.show();
170
- }, this );
171
- }
172
- });
173
- var hover = new Hover( { graph: graph } );
174
- }
175
-
176
- var createSeries = function(data) {
177
- var obj = JSON.parse(data);
178
- var series = [];
179
- for (var date in obj) {
180
- var value = obj[date];
181
- var point = { x: Date.parse(date)/1000, y: value };
182
- series.unshift(point);
183
- }
184
- return series;
185
- };
186
4
 
187
5
  var updateStatsSummary = function(data) {
188
6
  document.getElementById("txtProcessed").innerText = nf.format(data.processed);
@@ -211,12 +29,6 @@ var pulseBeacon = function() {
211
29
  window.setTimeout(() => { document.getElementById('beacon').classList.remove('pulse'); }, 1000);
212
30
  }
213
31
 
214
- // Render graphs
215
- var renderGraphs = function() {
216
- realtimeGraph();
217
- historyGraph();
218
- };
219
-
220
32
  var setSliderLabel = function(val) {
221
33
  document.getElementById('sldr-text').innerText = Math.round(parseFloat(val) / 1000) + ' sec';
222
34
  }
@@ -227,8 +39,6 @@ var ready = (callback) => {
227
39
  }
228
40
 
229
41
  ready(() => {
230
- renderGraphs();
231
-
232
42
  var sldr = document.getElementById('sldr');
233
43
  if (typeof localStorage.sidekiqTimeInterval !== 'undefined') {
234
44
  sldr.value = localStorage.sidekiqTimeInterval;
@@ -236,44 +46,14 @@ ready(() => {
236
46
  }
237
47
 
238
48
  sldr.addEventListener("change", event => {
239
- clearInterval(poller);
240
49
  localStorage.sidekiqTimeInterval = sldr.value;
241
50
  setSliderLabel(sldr.value);
242
- resetGraphs();
243
- renderGraphs();
51
+ sldr.dispatchEvent(
52
+ new CustomEvent("interval:update", { bubbles: true, detail: sldr.value })
53
+ );
244
54
  });
245
55
 
246
56
  sldr.addEventListener("mousemove", event => {
247
57
  setSliderLabel(sldr.value);
248
58
  });
249
59
  });
250
-
251
- // Reset graphs
252
- var resetGraphs = function() {
253
- document.getElementById('realtime').innerHTML = '';
254
- document.getElementById('history').innerHTML = '';
255
- };
256
-
257
- // Resize graphs after resizing window
258
- var debounce = function(fn, timeout) {
259
- var timeoutID = -1;
260
- return function() {
261
- if (timeoutID > -1) {
262
- window.clearTimeout(timeoutID);
263
- }
264
- timeoutID = window.setTimeout(fn, timeout);
265
- }
266
- };
267
-
268
- window.onresize = function() {
269
- var prevWidth = window.innerWidth;
270
- return debounce(function () {
271
- var currWidth = window.innerWidth;
272
- if (prevWidth !== currWidth) {
273
- prevWidth = currWidth;
274
- clearInterval(poller);
275
- resetGraphs();
276
- renderGraphs();
277
- }
278
- }, 125);
279
- }();