Skip to content

Commit

Permalink
fix: handle pending promise in edge (#8)
Browse files Browse the repository at this point in the history
* fix: handle pending promise in edge

* fix: handle pending promise in edge

* fix: ignore any

* fix: use correct type

* test: await pending promises

* docs: add pending promise
  • Loading branch information
chronark authored May 11, 2022
1 parent ad0663e commit b60e4f3
Show file tree
Hide file tree
Showing 8 changed files with 309 additions and 4,802 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ redis-server

./**/yarn.lock
./**/package-lock.json
./**/pnpm-lock.yam
./**/pnpm-lock.yaml

*.log
.vercel
66 changes: 58 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,29 +99,50 @@ return "Here you go!";

The `limit` method returns some more metadata that might be useful to you:

```ts
````ts
export type RatelimitResponse = {
/**
* Whether the request may pass(true) or exceeded the limit(false)
*/
success: boolean;

/**
* Maximum number of requests allowed within a window.
*/
limit: number;

/**
* How many requests the user has left within the current window.
*/
remaining: number;

/**
* Unix timestamp in milliseconds when the limits are reset.
*/
reset: number;

/**
* For the MultiRegion setup we do some synchronizing in the background, after returning the current limit.
* In most case you can simply ignore this.
*
* On Vercel Edge or Cloudflare workers, you need to explicitely handle the pending Promise like this:
*
* **Vercel Edge:**
* https://nextjs.org/docs/api-reference/next/server#nextfetchevent
*
* ```ts
* const { pending } = await ratelimit.limit("id")
* event.waitUntil(pending)
* ```
*
* **Cloudflare Worker:**
* https://developers.cloudflare.com/workers/runtime-apis/fetch-event/#syntax-module-worker
*
* ```ts
* const { pending } = await ratelimit.limit("id")
* context.waitUntil(pending)
* ```
*/
pending: Promise<unknown>;
};
```
````

### Block until ready

Expand Down Expand Up @@ -181,9 +202,15 @@ import { Redis } from "@upstash/redis";
// Create a new ratelimiter, that allows 10 requests per 10 seconds
const ratelimit = new MultiRegionRatelimit({
redis: [
new Redis({/* auth */}),
new Redis({/* auth */}),
new Redis({/* auth */}),
new Redis({
/* auth */
}),
new Redis({
/* auth */
}),
new Redis({
/* auth */
}),
],
limiter: Ratelimit.slidingWindow(10, "10 s"),
});
Expand All @@ -194,6 +221,29 @@ const identifier = "api";
const { success } = await ratelimit.limit(identifier);
```

### Asynchronous synchronization between databases

The MultiRegion setup will do some synchronization between databases after
returning the current limit. This can lead to problems on Cloudflare Workers and
therefore Vercel Edge functions, because dangling promises must be taken care
of:

**Vercel Edge:**
[docs](https://nextjs.org/docs/api-reference/next/server#nextfetchevent)

```ts
const { pending } = await ratelimit.limit("id");
event.waitUntil(pending);
```

**Cloudflare Worker:**
[docs](https://developers.cloudflare.com/workers/runtime-apis/fetch-event/#syntax-module-worker)

```ts
const { pending } = await ratelimit.limit("id");
context.waitUntil(pending);
```

### Example

Let's assume you have customers in the US and Europe. In this case you can
Expand Down
Loading

0 comments on commit b60e4f3

Please sign in to comment.