@@ -34,14 +34,60 @@ class TokenBucket implements RateLimiter {
3434 timestamp : number ,
3535 tokens = 1
3636 ) : Promise < RateLimiterResponse > {
37- throw Error ( `TokenBucket.processRequest not implemented, ${ this } ` ) ;
37+ // set an expiry for key-pairs in redis to 24 hours
38+ const bucketExpiry = 86400000 ;
39+
40+ // attempt to get the value for the uuid from the redis cache
41+ const bucketJSON = await this . client . get ( 'uuid' ) ;
42+
43+ // if the response is null, we need to create bucket for the user
44+ if ( bucketJSON === null ) {
45+ if ( tokens > this . capacity ) {
46+ // reject the request, not enough tokens in bucket
47+ return {
48+ success : false ,
49+ tokens : 10 ,
50+ } ;
51+ }
52+ const newUserBucket : RedisBucket = {
53+ tokens : this . capacity - tokens ,
54+ timestamp,
55+ } ;
56+ await this . client . setEx ( uuid , bucketExpiry , JSON . stringify ( newUserBucket ) ) ;
57+ return {
58+ success : true ,
59+ tokens : newUserBucket . tokens ,
60+ } ;
61+ }
62+
63+ const bucket : RedisBucket = await JSON . parse ( bucketJSON ) ;
64+ // TODO check the timestamp on bucket and update however many tokens are supposed to be in there
65+
66+ const timeSinceLastQuery : number = timestamp - bucket . timestamp ;
67+
68+ if ( bucket . tokens < tokens ) {
69+ // reject the request, not enough tokens in bucket
70+ return {
71+ success : false ,
72+ tokens : bucket . tokens ,
73+ } ;
74+ }
75+ const updatedUserBucket = {
76+ tokens : bucket . tokens - tokens ,
77+ timestamp,
78+ } ;
79+ await this . client . setEx ( uuid , bucketExpiry , JSON . stringify ( updatedUserBucket ) ) ;
80+ return {
81+ success : true ,
82+ tokens : updatedUserBucket . tokens ,
83+ } ;
3884 }
3985
4086 /**
4187 * Resets the rate limiter to the intial state by clearing the redis store.
4288 */
4389 reset ( ) : void {
44- throw Error ( `TokenBucket.reset not implemented, ${ this } ` ) ;
90+ this . client . flushAll ( ) ;
4591 }
4692}
4793
0 commit comments