Skip to content

Instantly share code, notes, and snippets.

@themasch
Last active December 29, 2015 18:39
Show Gist options
  • Save themasch/7712130 to your computer and use it in GitHub Desktop.
Save themasch/7712130 to your computer and use it in GitHub Desktop.
speed limited stream
var Stream = require('stream')
, util = require('util')
util.inherits(Limited, Stream.Transform)
function Limited( options ) {
if(!(this instanceof Limited)) {
return new Limited( options )
}
this.options = options || {}
Stream.Transform.call(this, this.options)
this._limit = this.options.limit || 0
this._stopwatch = new TimeWindowBuffer(10)
this._speed = 0
}
Limited.prototype._transform = function(chunk, enc, cb) {
var len = chunk.length;
if(this._limit > 0 && this._speed > this._limit) {
var delay = (this._speed / this._limit) * 1000
setTimeout(
function() {
cb(null, chunk)
this._stopwatch.push(len)
}.bind(this),
Math.min(delay, 10000)
)
}
else {
cb(null, chunk)
this._stopwatch.push(len)
}
this._speed = this._stopwatch.calc()
if(isNaN(this._speed)) {
this._speed = 0;
}
//console.log(this._speed/1000, 'KB/s');
}
function TimeWindowBuffer(seconds) {
this._maxAge = seconds * 1000
this._buffer = []
}
TimeWindowBuffer.prototype.push = function(value) {
this._buffer.push({
time: Date.now(),
value: value
})
}
TimeWindowBuffer.prototype._trim = function() {
var maxAge = Date.now() - this._maxAge
this._buffer = this._buffer.filter(function(x) {
return x.time > maxAge
})
}
TimeWindowBuffer.prototype.calc = function(cb) {
this._trim()
if(this._buffer.length === 0) {
return 0
}
var secondCnt = 0
var secondSum = 0
var startTime = this._buffer[0].time
var tmp = 0
for(var x=0;x<this._buffer.length;x++) {
if(this._buffer[x].time > startTime + 1000) {
secondSum += tmp
secondCnt ++
startTime = this._buffer[x].time
tmp = 0;
}
tmp += this._buffer[x].value
}
secondCnt++
secondSum += tmp
//console.log(seconds, seconds.length, this._buffer.length)
return secondSum / secondCnt
}
module.exports = Limited
@jhermsmeier
Copy link

Seems perfectly legit to me. What exactly are you using it for?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment