Skip to content

Commit 1dbd7e0

Browse files
committed
removed null as a type of previousTokens
1 parent a950262 commit 1dbd7e0

File tree

2 files changed

+34
-20
lines changed

2 files changed

+34
-20
lines changed

src/@types/rateLimit.d.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ export interface RedisBucket {
2525

2626
export interface RedisWindow {
2727
currentTokens: number;
28-
// null if limiter is currently on the initial fixed window
29-
previousTokens: number | null;
28+
previousTokens: number;
3029
fixedWindowStart?: number;
3130
}
3231

test/rateLimiters/slidingWindowCounter.test.ts

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ async function setTokenCountInClient(
2828
redisClient: ioredis.Redis,
2929
uuid: string,
3030
currentTokens: number,
31-
previousTokens: number | null,
31+
previousTokens: number,
3232
fixedWindowStart: number
3333
) {
3434
const value: RedisWindow = { currentTokens, previousTokens, fixedWindowStart };
3535
await redisClient.set(uuid, JSON.stringify(value));
3636
}
3737

38-
xdescribe('Test TokenBucket Rate Limiter', () => {
38+
xdescribe('Test SlidingWindowCounter Rate Limiter', () => {
3939
beforeEach(async () => {
4040
// init a mock redis cache
4141
client = new RedisMock();
@@ -50,14 +50,29 @@ xdescribe('Test TokenBucket Rate Limiter', () => {
5050
afterEach(() => {
5151
client.flushall();
5252
});
53+
5354
test('fixed window is initially empty', async () => {
55+
setTokenCountInClient(client, user1, 0, 0, timestamp);
56+
57+
// window is intially empty
58+
const withdraw5 = 5;
59+
expect((await limiter.processRequest(user1, timestamp, withdraw5)).tokens).toBe(
60+
CAPACITY - withdraw5
61+
);
62+
const tokenCountFull = await getWindowFromClient(client, user1);
63+
expect(tokenCountFull.currentTokens).toBe(CAPACITY - withdraw5);
64+
expect(tokenCountFull.previousTokens).toBe(0);
65+
});
66+
67+
test('fixed window and cache are initially empty', async () => {
5468
// window is intially empty
5569
const withdraw5 = 5;
5670
expect((await limiter.processRequest(user1, timestamp, withdraw5)).tokens).toBe(
5771
CAPACITY - withdraw5
5872
);
5973
const tokenCountFull = await getWindowFromClient(client, user1);
6074
expect(tokenCountFull.currentTokens).toBe(CAPACITY - withdraw5);
75+
expect(tokenCountFull.previousTokens).toBe(0);
6176
});
6277

6378
test('fixed window is partially full and request has leftover tokens', async () => {
@@ -80,15 +95,15 @@ xdescribe('Test TokenBucket Rate Limiter', () => {
8095
// window partially full and no leftover tokens after request
8196
test('fixed window is partially full and request has no leftover tokens', async () => {
8297
const initial = 6;
83-
await setTokenCountInClient(client, user2, initial, null, timestamp);
98+
await setTokenCountInClient(client, user2, initial, 0, timestamp);
8499
expect((await limiter.processRequest(user2, timestamp, initial)).tokens).toBe(0);
85100
const tokenCountPartialToEmpty = await getWindowFromClient(client, user2);
86101
expect(tokenCountPartialToEmpty.currentTokens).toBe(0);
87102
});
88103

89104
// Window initially full but enough time elapsed to paritally fill window since last request
90-
test('fixed window is initially full but after new fixed window is initialized request is allowed', async () => {
91-
await setTokenCountInClient(client, user4, 10, null, timestamp);
105+
test('current window is initially full but after new fixed window is initialized request is allowed', async () => {
106+
await setTokenCountInClient(client, user4, 10, 0, timestamp);
92107
// tokens returned in processRequest is equal to the capacity
93108
// still available in the fixed window
94109
expect(
@@ -111,7 +126,7 @@ xdescribe('Test TokenBucket Rate Limiter', () => {
111126
// to set rolling window at 75% of previous fixed window)
112127

113128
// to set initial fixedWindowStart
114-
await setTokenCountInClient(client, user4, 0, null, timestamp);
129+
await setTokenCountInClient(client, user4, 0, 0, timestamp);
115130

116131
// large request at very end of first fixed window
117132
await limiter.processRequest(user4, timestamp + WINDOW_SIZE, 8);
@@ -135,7 +150,7 @@ xdescribe('Test TokenBucket Rate Limiter', () => {
135150
// to set rolling window at 50% of previous fixed window)
136151

137152
// to set initial fixedWindowStart
138-
await setTokenCountInClient(client, user4, 0, null, timestamp);
153+
await setTokenCountInClient(client, user4, 0, 0, timestamp);
139154

140155
// large request at very end of first fixed window
141156
await limiter.processRequest(user4, timestamp + WINDOW_SIZE, 8);
@@ -159,7 +174,7 @@ xdescribe('Test TokenBucket Rate Limiter', () => {
159174
// to set rolling window at 25% of previous fixed window)
160175

161176
// to set initial fixedWindowStart
162-
await setTokenCountInClient(client, user4, 0, null, timestamp);
177+
await setTokenCountInClient(client, user4, 0, 0, timestamp);
163178

164179
// large request at very end of first fixed window
165180
await limiter.processRequest(user4, timestamp + WINDOW_SIZE, 8);
@@ -193,7 +208,7 @@ xdescribe('Test TokenBucket Rate Limiter', () => {
193208
test('window is partially full but not enough time elapsed to reach new window', async () => {
194209
const initRequest = 6;
195210

196-
await setTokenCountInClient(client, user2, initRequest, null, timestamp);
211+
await setTokenCountInClient(client, user2, initRequest, 0, timestamp);
197212
// expect remaining tokens to be 4, b/c the 5 token request should be blocked
198213
expect(
199214
(await limiter.processRequest(user2, timestamp + WINDOW_SIZE, 5)).tokens
@@ -210,7 +225,7 @@ xdescribe('Test TokenBucket Rate Limiter', () => {
210225
// to set rolling window at 75% of previous fixed window)
211226

212227
// to set initial fixedWindowStart
213-
await setTokenCountInClient(client, user4, 0, null, timestamp);
228+
await setTokenCountInClient(client, user4, 0, 0, timestamp);
214229

215230
const initRequest = 8;
216231

@@ -236,7 +251,7 @@ xdescribe('Test TokenBucket Rate Limiter', () => {
236251
// to set rolling window at 50% of previous fixed window)
237252

238253
// to set initial fixedWindowStart
239-
await setTokenCountInClient(client, user4, 0, null, timestamp);
254+
await setTokenCountInClient(client, user4, 0, 0, timestamp);
240255

241256
const initRequest = 8;
242257

@@ -261,7 +276,7 @@ xdescribe('Test TokenBucket Rate Limiter', () => {
261276
// to set rolling window at 25% of previous fixed window)
262277

263278
// to set initial fixedWindowStart
264-
await setTokenCountInClient(client, user4, 0, null, timestamp);
279+
await setTokenCountInClient(client, user4, 0, 0, timestamp);
265280

266281
const initRequest = 8;
267282

@@ -308,7 +323,7 @@ xdescribe('Test TokenBucket Rate Limiter', () => {
308323
// Fill up user 1's window
309324
const value: RedisWindow = {
310325
currentTokens: 10,
311-
previousTokens: null,
326+
previousTokens: 0,
312327
fixedWindowStart: timestamp,
313328
};
314329
await client.set(user1, JSON.stringify(value));
@@ -321,7 +336,7 @@ xdescribe('Test TokenBucket Rate Limiter', () => {
321336
});
322337

323338
test('fixed window and current/previous tokens update as expected', async () => {
324-
await setTokenCountInClient(client, user1, 0, null, timestamp);
339+
await setTokenCountInClient(client, user1, 0, 0, timestamp);
325340
// fills first window with 4 tokens
326341
await limiter.processRequest(user1, timestamp, 5);
327342
// fills second window with 5 tokens
@@ -367,7 +382,7 @@ xdescribe('Test TokenBucket Rate Limiter', () => {
367382
const requested = 6;
368383
const user3Tokens = 8;
369384
// Add tokens for user 3 so we have both a user that exists in the store (3) and one that doesn't (2)
370-
await setTokenCountInClient(client, user3, user3Tokens, null, timestamp);
385+
await setTokenCountInClient(client, user3, user3Tokens, 0, timestamp);
371386

372387
// issue a request for user 1;
373388
await limiter.processRequest(user1, timestamp, requested);
@@ -401,9 +416,9 @@ xdescribe('Test TokenBucket Rate Limiter', () => {
401416

402417
test('all windows should be able to be reset', async () => {
403418
const tokens = 5;
404-
await setTokenCountInClient(client, user1, tokens, null, timestamp);
405-
await setTokenCountInClient(client, user2, tokens, null, timestamp);
406-
await setTokenCountInClient(client, user3, tokens, null, timestamp);
419+
await setTokenCountInClient(client, user1, tokens, 0, timestamp);
420+
await setTokenCountInClient(client, user2, tokens, 0, timestamp);
421+
await setTokenCountInClient(client, user3, tokens, 0, timestamp);
407422

408423
limiter.reset();
409424

0 commit comments

Comments
 (0)