40 lines
1.3 KiB
JavaScript
40 lines
1.3 KiB
JavaScript
const windowMs = 30000;
|
|
const minimumSpanMs = 4000;
|
|
const samplesByJob = new Map();
|
|
|
|
export function updateSpeeds(jobs) {
|
|
const now = performance.now();
|
|
const seenIds = new Set();
|
|
|
|
for (const job of jobs) {
|
|
seenIds.add(job.id);
|
|
let samples = samplesByJob.get(job.id) || [];
|
|
const last = samples[samples.length - 1];
|
|
const progressWentBack = last && job.bytesDone < last.bytes;
|
|
const notTransferring = job.status !== "downloading" && job.status !== "extracting" && job.status !== "moving";
|
|
if (progressWentBack || notTransferring || (last && last.status !== job.status)) {
|
|
samples = [];
|
|
}
|
|
|
|
samples.push({ bytes: job.bytesDone, time: now, status: job.status });
|
|
while (samples.length > 2 && now - samples[1].time >= windowMs) {
|
|
samples.shift();
|
|
}
|
|
samplesByJob.set(job.id, samples);
|
|
}
|
|
|
|
for (const id of samplesByJob.keys()) {
|
|
if (!seenIds.has(id)) samplesByJob.delete(id);
|
|
}
|
|
}
|
|
|
|
export function speedOf(jobId) {
|
|
const samples = samplesByJob.get(jobId);
|
|
if (!samples || samples.length < 2) return 0;
|
|
const first = samples[0];
|
|
const last = samples[samples.length - 1];
|
|
const spanMs = last.time - first.time;
|
|
if (spanMs < minimumSpanMs) return 0;
|
|
return ((last.bytes - first.bytes) * 1000) / spanMs;
|
|
}
|