2019-05-29 17:20:18 +08:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
const { Transform } = require('stream');
|
|
|
|
|
|
|
|
module.exports = class Throttler extends Transform {
|
|
|
|
constructor (pgstream, ...args) {
|
|
|
|
super(...args);
|
|
|
|
|
|
|
|
this.pgstream = pgstream;
|
|
|
|
|
|
|
|
this.sampleLength = global.settings.copy_from_maximum_slow_input_speed_interval || 15;
|
|
|
|
this.minimunBytesPerSecondThershold = global.settings.copy_from_minimum_input_speed || 0;
|
|
|
|
this.byteCount = 0;
|
|
|
|
this.bytesPerSecondHistory = [];
|
|
|
|
|
|
|
|
this._interval = setInterval(this._updateMetrics.bind(this), 1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
_updateMetrics () {
|
|
|
|
this.bytesPerSecondHistory.push(this.byteCount);
|
|
|
|
this.byteCount = 0;
|
|
|
|
|
2019-11-19 23:45:52 +08:00
|
|
|
if (this.bytesPerSecondHistory.length > this.sampleLength) {
|
2019-05-29 17:20:18 +08:00
|
|
|
this.bytesPerSecondHistory.shift();
|
|
|
|
}
|
|
|
|
|
2019-11-19 23:53:49 +08:00
|
|
|
let doesNotReachThreshold = 0;
|
2019-05-29 17:20:18 +08:00
|
|
|
|
|
|
|
for (const bytesPerSecond of this.bytesPerSecondHistory) {
|
|
|
|
if (bytesPerSecond <= this.minimunBytesPerSecondThershold) {
|
2019-11-19 23:53:49 +08:00
|
|
|
doesNotReachThreshold += 1;
|
2019-05-29 17:20:18 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-19 23:53:49 +08:00
|
|
|
if (doesNotReachThreshold >= this.sampleLength) {
|
2019-05-29 17:20:18 +08:00
|
|
|
clearInterval(this._interval);
|
|
|
|
this.pgstream.emit('error', new Error('Connection closed by server: input data too slow'));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_transform (chunk, encoding, callback) {
|
|
|
|
this.byteCount += chunk.length;
|
|
|
|
callback(null, chunk);
|
|
|
|
}
|
|
|
|
|
|
|
|
_flush (callback) {
|
|
|
|
clearInterval(this._interval);
|
|
|
|
callback();
|
|
|
|
}
|
2019-05-29 17:38:25 +08:00
|
|
|
};
|