jm-tech-power-official/Flash Download
A desktop download manager that opens up to 32 connections against one file and can send each of them out a different proxy route.
Public
Uncategorized
Clone
jm-tech-power-official/flash-download.jmproj
src/main/engine/limiter.js
'use strict';
/**
* Token bucket shared by every lane in the app, so a speed limit applies to the
* download as a whole rather than per connection (16 lanes x 1 MB/s is not a
* 1 MB/s limit, and users mean the former).
*/
class Limiter {
constructor() {
this.bps = 0; // 0 === unlimited
this.tokens = 0;
this.waiters = [];
this.timer = null;
}
setLimit(bytesPerSecond) {
this.bps = Math.max(0, Number(bytesPerSecond) || 0);
this.tokens = this.bps;
if (this.bps && !this.timer) {
this.timer = setInterval(() => this.refill(), 100);
if (this.timer.unref) this.timer.unref();
} else if (!this.bps && this.timer) {
clearInterval(this.timer);
this.timer = null;
this.release();
}
}
/** @returns {Promise<void>|null} null means "proceed immediately" */
take(bytes) {
if (!this.bps) return null;
this.tokens -= bytes;
if (this.tokens >= 0) return null;
return new Promise((resolve) => this.waiters.push(resolve));
}
refill() {
this.tokens = Math.min(this.bps, this.tokens + this.bps / 10);
if (this.tokens >= 0) this.release();
}
release() {
const waiting = this.waiters;
this.waiters = [];
for (const resolve of waiting) resolve();
}
stop() {
if (this.timer) clearInterval(this.timer);
this.timer = null;
this.release();
}
}
module.exports = { Limiter };