Skip to content

Commit

Permalink
Implement set method for all limiters
Browse files Browse the repository at this point in the history
  • Loading branch information
animirr committed Jan 14, 2020
1 parent 9f7bed0 commit 4fea264
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 2 deletions.
4 changes: 4 additions & 0 deletions lib/RateLimiterAbstract.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ module.exports = class RateLimiterAbstract {
throw new Error("You have to implement the method 'get'!");
}

set() {
throw new Error("You have to implement the method 'set'!");
}

block() {
throw new Error("You have to implement the method 'block'!");
}
Expand Down
13 changes: 12 additions & 1 deletion lib/RateLimiterMemory.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,18 @@ class RateLimiterMemory extends RateLimiterAbstract {
const initPoints = this.points + 1;

this._memoryStorage.set(this.getKey(key), initPoints, secDuration);
return Promise.resolve(new RateLimiterRes(0, msDuration, initPoints));
return Promise.resolve(
new RateLimiterRes(0, msDuration === 0 ? -1 : msDuration, initPoints)
);
}

set(key, points, secDuration) {
const msDuration = (secDuration >= 0 ? secDuration : this.duration) * 1000;

this._memoryStorage.set(this.getKey(key), points, secDuration);
return Promise.resolve(
new RateLimiterRes(0, msDuration === 0 ? -1 : msDuration, points)
);
}

get(key) {
Expand Down
15 changes: 15 additions & 0 deletions lib/RateLimiterStoreAbstract.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,21 @@ module.exports = class RateLimiterStoreAbstract extends RateLimiterAbstract {
return this._block(this.getKey(key), this.points + 1, msDuration, options);
}

/**
* Set points by key for any duration
*
* @param key
* @param points
* @param secDuration
* @param {Object} options
*
* @return Promise<RateLimiterRes>
*/
set(key, points, secDuration, options = {}) {
const msDuration = (secDuration >= 0 ? secDuration : this.duration) * 1000;
return this._block(this.getKey(key), points, msDuration, options);
}

/**
*
* @param key
Expand Down
4 changes: 4 additions & 0 deletions lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ export class RateLimiterAbstract {

get(key: string | number, options?: {[key: string]: any }): Promise<RateLimiterRes|null>;

set(key: string | number, points: number, secDuration: number, options?: {[key: string]: any }): Promise<RateLimiterRes>;

delete(key: string | number, options?: {[key: string]: any }): Promise<boolean>;

getKey(key: string | number): string;
Expand Down Expand Up @@ -140,6 +142,8 @@ export class RateLimiterMongo extends RateLimiterStoreAbstract {

get(key: string | number, options?: IRateLimiterMongoFunctionOptions): Promise<RateLimiterRes|null>;

set(key: string | number, points: number, secDuration: number, options?: IRateLimiterMongoFunctionOptions): Promise<RateLimiterRes>;

delete(key: string | number, options?: IRateLimiterMongoFunctionOptions): Promise<boolean>;
}

Expand Down
35 changes: 35 additions & 0 deletions test/RateLimiterMemory.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -327,4 +327,39 @@ describe('RateLimiterMemory with fixed window', function RateLimiterMemoryTest()
done(err);
});
});

it('set points by key', (done) => {
const testKey = 'set';
const rateLimiter = new RateLimiterMemory({ points: 10, duration: 1 });
rateLimiter.set(testKey, 12)
.then(() => {
rateLimiter.get(testKey)
.then((res) => {
expect(res.consumedPoints).to.equal(12);
done();
});
})
.catch((err) => {
done(err);
});
});

it('set points by key forever', (done) => {
const testKey = 'setforever';
const rateLimiter = new RateLimiterMemory({ points: 10, duration: 1 });
rateLimiter.set(testKey, 12, 0)
.then(() => {
setTimeout(() => {
rateLimiter.get(testKey)
.then((res) => {
expect(res.consumedPoints).to.equal(12);
expect(res.msBeforeNext).to.equal(-1);
done();
});
}, 1100);
})
.catch((err) => {
done(err);
});
});
});
37 changes: 36 additions & 1 deletion test/RateLimiterRedis.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -764,7 +764,42 @@ describe('RateLimiterRedis with fixed window', function RateLimiterRedisTest() {
expect(res.msBeforeNext).to.equal(-1);
done();
});
}, 1000);
}, 2000);
})
.catch((err) => {
done(err);
});
});

it('set points by key', (done) => {
const testKey = 'set';
const rateLimiter = new RateLimiterRedis({ storeClient: redisMockClient, points: 1, duration: 1 });
rateLimiter.set(testKey, 12)
.then(() => {
rateLimiter.get(testKey)
.then((res) => {
expect(res.consumedPoints).to.equal(12);
done();
});
})
.catch((err) => {
done(err);
});
});

it('set points by key forever', (done) => {
const testKey = 'setforever';
const rateLimiter = new RateLimiterRedis({ storeClient: redisMockClient, points: 1, duration: 1 });
rateLimiter.set(testKey, 12, 0)
.then(() => {
setTimeout(() => {
rateLimiter.get(testKey)
.then((res) => {
expect(res.consumedPoints).to.equal(12);
expect(res.msBeforeNext).to.equal(-1);
done();
});
}, 1100);
})
.catch((err) => {
done(err);
Expand Down

0 comments on commit 4fea264

Please sign in to comment.