Support IO token bucket capacity > refill rate

This commit is contained in:
Calvin Montgomery 2018-11-15 23:04:03 -08:00
parent 8456b6a125
commit 4c9e85b293
4 changed files with 21 additions and 7 deletions

View File

@ -2,7 +2,7 @@
"author": "Calvin Montgomery", "author": "Calvin Montgomery",
"name": "CyTube", "name": "CyTube",
"description": "Online media synchronizer and chat", "description": "Online media synchronizer and chat",
"version": "3.61.1", "version": "3.62.0",
"repository": { "repository": {
"url": "http://github.com/calzoneman/sync" "url": "http://github.com/calzoneman/sync"
}, },

View File

@ -397,11 +397,16 @@ function preprocessConfig(cfg) {
}); });
if (!cfg.io.throttle) { if (!cfg.io.throttle) {
cfg.io.throttle = { cfg.io.throttle = {};
'in-rate-limit': Infinity
};
} }
cfg.io.throttle = Object.assign({
'in-rate-limit': Infinity
}, cfg.io.throttle);
cfg.io.throttle = Object.assign({
'bucket-capacity': cfg.io.throttle['in-rate-limit']
}, cfg.io.throttle);
return cfg; return cfg;
} }

View File

@ -251,16 +251,17 @@ class IOServer {
} }
setRateLimiter(socket) { setRateLimiter(socket) {
const thunk = () => Config.get('io.throttle.in-rate-limit'); const refillRate = () => Config.get('io.throttle.in-rate-limit');
const capacity = () => Config.get('io.throttle.bucket-capacity');
socket._inRateLimit = new TokenBucket(thunk, thunk); socket._inRateLimit = new TokenBucket(capacity, refillRate);
socket.on('cytube:count-event', () => { socket.on('cytube:count-event', () => {
if (socket._inRateLimit.throttle()) { if (socket._inRateLimit.throttle()) {
LOGGER.warn( LOGGER.warn(
'Kicking client %s: exceeded in-rate-limit of %d', 'Kicking client %s: exceeded in-rate-limit of %d',
socket.context.ipAddress, socket.context.ipAddress,
thunk() refillRate()
); );
socket.emit('kick', { reason: 'Rate limit exceeded' }); socket.emit('kick', { reason: 'Rate limit exceeded' });

View File

@ -54,5 +54,13 @@ describe('TokenBucket', () => {
assert(!bucket.throttle()); assert(!bucket.throttle());
assert.strictEqual(bucket.count, 0); assert.strictEqual(bucket.count, 0);
}); });
it('handles infinite refill rate and capacity', () => {
bucket = new TokenBucket(Infinity, Infinity);
for (let i = 0; i < 100; i++) {
assert(!bucket.throttle(), 'should not throttle');
}
});
}); });
}); });