@@ -5,8 +5,13 @@ const RATE_LIMIT_WINDOW_SECONDS = 10;
55
66// Redis interface compatible with ioredis (Node) and upstash (Cloudflare Workers).
77type IRedis = {
8- incr : ( key : string ) => Promise < number > ;
9- expire : ( key : string , ttlSeconds : number ) => Promise < 0 | 1 > ;
8+ get : ( key : string ) => Promise < string | null > ;
9+ set (
10+ key : string ,
11+ value : string | number ,
12+ secondsToken ?: "EX" | "XX" ,
13+ seconds ?: number | string ,
14+ ) : Promise < "OK" > ;
1015} ;
1116
1217export async function rateLimit ( args : {
@@ -20,6 +25,7 @@ export async function rateLimit(args: {
2025 * @default 1.0
2126 */
2227 sampleRate ?: number ;
28+ logger ?: typeof console ;
2329} ) : Promise < RateLimitResult > {
2430 const { team, limitPerSecond, serviceConfig, redis, sampleRate = 1.0 } = args ;
2531
@@ -49,11 +55,25 @@ export async function rateLimit(args: {
4955 RATE_LIMIT_WINDOW_SECONDS ;
5056 const key = `rate-limit:${ serviceScope } :${ team . id } :${ timestampWindow } ` ;
5157
52- // Increment and get the current request count in this window.
53- const requestCount = await redis . incr ( key ) ;
58+ // first read the request count from redis
59+ const currentRequestCountFromRedis = Number ( ( await redis . get ( key ) ) || "0" ) ;
60+
61+ const requestCount = currentRequestCountFromRedis + 1 ;
62+
63+ // we are setting the request count, however we are not waiting on this to be complete
5464 if ( requestCount === 1 ) {
55- // For the first increment, set an expiration to clean up this key.
56- await redis . expire ( key , RATE_LIMIT_WINDOW_SECONDS ) ;
65+ // For the first increment, set an expiration to clean up this key (EX).
66+ redis
67+ . set ( key , requestCount , "EX" , RATE_LIMIT_WINDOW_SECONDS )
68+ . catch ( ( err ) => {
69+ console . error ( "failed to set request count" , err ) ;
70+ } ) ;
71+ } else {
72+ // For all other increments, just increment the request count.
73+ // only set it if it already exists (XX)
74+ redis . set ( key , requestCount , "XX" ) . catch ( ( err ) => {
75+ console . error ( "failed to increment request count" , err ) ;
76+ } ) ;
5777 }
5878
5979 // Get the limit for this window accounting for the sample rate.
0 commit comments