sidekiq 6.5.7 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of sidekiq might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Changes.md +20 -4
- data/{LICENSE → LICENSE.txt} +0 -0
- data/README.md +13 -12
- data/bin/sidekiq +3 -8
- data/bin/sidekiqload +15 -24
- data/lib/sidekiq/api.rb +51 -120
- data/lib/sidekiq/capsule.rb +110 -0
- data/lib/sidekiq/cli.rb +52 -60
- data/lib/sidekiq/client.rb +29 -16
- data/lib/sidekiq/component.rb +1 -0
- data/lib/sidekiq/config.rb +271 -0
- data/lib/sidekiq/deploy.rb +62 -0
- data/lib/sidekiq/embedded.rb +61 -0
- data/lib/sidekiq/fetch.rb +10 -11
- data/lib/sidekiq/job.rb +375 -10
- data/lib/sidekiq/job_logger.rb +1 -1
- data/lib/sidekiq/job_retry.rb +8 -8
- data/lib/sidekiq/job_util.rb +4 -4
- data/lib/sidekiq/launcher.rb +36 -46
- data/lib/sidekiq/logger.rb +1 -26
- data/lib/sidekiq/manager.rb +9 -11
- data/lib/sidekiq/metrics/query.rb +2 -2
- data/lib/sidekiq/metrics/shared.rb +4 -3
- data/lib/sidekiq/metrics/tracking.rb +18 -18
- data/lib/sidekiq/middleware/chain.rb +7 -9
- data/lib/sidekiq/middleware/current_attributes.rb +8 -13
- data/lib/sidekiq/paginator.rb +8 -0
- data/lib/sidekiq/processor.rb +17 -26
- data/lib/sidekiq/rails.rb +2 -8
- data/lib/sidekiq/redis_client_adapter.rb +9 -45
- data/lib/sidekiq/redis_connection.rb +11 -111
- data/lib/sidekiq/scheduled.rb +19 -20
- data/lib/sidekiq/testing.rb +5 -33
- data/lib/sidekiq/transaction_aware_client.rb +4 -5
- data/lib/sidekiq/version.rb +2 -1
- data/lib/sidekiq/web/application.rb +4 -1
- data/lib/sidekiq/web/csrf_protection.rb +1 -1
- data/lib/sidekiq/web/helpers.rb +8 -29
- data/lib/sidekiq/web.rb +2 -17
- data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
- data/lib/sidekiq.rb +76 -274
- data/sidekiq.gemspec +29 -5
- data/web/assets/javascripts/base-charts.js +106 -0
- data/web/assets/javascripts/dashboard-charts.js +166 -0
- data/web/assets/javascripts/dashboard.js +3 -223
- data/web/assets/javascripts/metrics.js +90 -116
- data/web/assets/stylesheets/application-rtl.css +2 -91
- data/web/assets/stylesheets/application.css +21 -296
- data/web/locales/ar.yml +70 -70
- data/web/locales/cs.yml +62 -62
- data/web/locales/da.yml +52 -52
- data/web/locales/de.yml +65 -65
- data/web/locales/el.yml +2 -7
- data/web/locales/en.yml +76 -70
- data/web/locales/es.yml +68 -68
- data/web/locales/fa.yml +65 -65
- data/web/locales/fr.yml +67 -67
- data/web/locales/he.yml +65 -64
- data/web/locales/hi.yml +59 -59
- data/web/locales/it.yml +53 -53
- data/web/locales/ja.yml +64 -68
- data/web/locales/ko.yml +52 -52
- data/web/locales/lt.yml +66 -66
- data/web/locales/nb.yml +61 -61
- data/web/locales/nl.yml +52 -52
- data/web/locales/pl.yml +45 -45
- data/web/locales/pt-br.yml +59 -69
- data/web/locales/pt.yml +51 -51
- data/web/locales/ru.yml +67 -66
- data/web/locales/sv.yml +53 -53
- data/web/locales/ta.yml +60 -60
- data/web/locales/uk.yml +62 -61
- data/web/locales/ur.yml +64 -64
- data/web/locales/vi.yml +67 -67
- data/web/locales/zh-cn.yml +1 -0
- data/web/locales/zh-tw.yml +10 -1
- data/web/views/_footer.erb +5 -2
- data/web/views/busy.erb +6 -1
- data/web/views/dashboard.erb +36 -5
- data/web/views/metrics.erb +30 -19
- data/web/views/metrics_for_job.erb +16 -34
- metadata +56 -28
- data/lib/sidekiq/delay.rb +0 -43
- data/lib/sidekiq/extensions/action_mailer.rb +0 -48
- data/lib/sidekiq/extensions/active_record.rb +0 -43
- data/lib/sidekiq/extensions/class_methods.rb +0 -43
- data/lib/sidekiq/extensions/generic_proxy.rb +0 -33
- data/lib/sidekiq/metrics/deploy.rb +0 -47
- data/lib/sidekiq/worker.rb +0 -370
- data/web/assets/javascripts/graph.js +0 -16
@@ -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
|
-
|
243
|
-
|
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
|
-
}();
|