Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added rate limit to cf-worker example #16

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion examples/nodejs-cf-worker/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)

report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
Expand Down
65 changes: 64 additions & 1 deletion examples/nodejs-cf-worker/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,17 @@
* @see https://developers.cloudflare.com/workers/configuration/secrets/
*/

import { DurableObject } from 'cloudflare:workers';
import { z } from 'zod';

// const WHITEGLOVE_MAP = {
// "api.thegraph.com/subgraphs/name/schmidsi/anudit-lens": {
// ""
// "rateLimit": 100,
// "rateLimitWindow": 6
// }
// }

const GraphqlReqSchema = z.object({
query: z.string().min(1),
operationName: z.string().optional().nullable(),
Expand All @@ -41,6 +50,36 @@ export default {
return new Response('Unsupported', { status: 400 });
}

// TODO: per subgraph rate limiting
const id = env.RATE_LIMITER.idFromName('global');

console.log('Hello Pranav');

try {
const stub = env.RATE_LIMITER.get(id);
// const milliseconds_to_next_request = await ;

// console.log(milliseconds_to_next_request, 'milliseconds_to_next_request')

if (await stub.rateLimit()) {
// Alternatively one could sleep for the necessary length of time
return new Response(
JSON.stringify({
errors: [
{
message:
'Rate limit on ENS communtiy key exceeded. Try again later or got to https://thegraph.com/studio to create your own API key. Find the ENS subgraph here: https://thegraph.com/explorer/subgraphs/5XqPmWe6gjyrJtFn9cLy237i4cWw2j9HcUJEXsP5qGtH?v=1&view=Overview&chain=arbitrum-one',
},
],
}),
{ status: 429 }
);
}
} catch (error) {
console.log(error, 'error')
return new Response('Could not connect to rate limiter', { status: 502 });
}

const response = await querySubgraph(req, env);
if (response.status !== 200) {
return new Response(response.statusText, { status: response.status });
Expand All @@ -66,8 +105,32 @@ async function querySubgraph(req: Request, env: Env) {
method: 'POST',
body: JSON.stringify(gqlRequest),
headers: {
authorization: `Bearer ${env.API_KEY}`,
// authorization: `Bearer ${env.API_KEY}`,
'Content-Type': 'application/json',
},
});
}

export class RateLimiter extends DurableObject {
static milliseconds_per_request = 10000;

lastRequest: number;

constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env);
this.lastRequest = 0;
}

async rateLimit(): Promise<boolean> {
const now = Date.now();

console.log(now, this.lastRequest, RateLimiter.milliseconds_per_request);

if (now - this.lastRequest > RateLimiter.milliseconds_per_request) {
this.lastRequest = now;
return false;
} else {
return true
}
}
}
5 changes: 3 additions & 2 deletions examples/nodejs-cf-worker/worker-configuration.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// Generated by Wrangler on Mon May 13 2024 08:41:07 GMT-1000 (Hawaii-Aleutian Standard Time)
// Generated by Wrangler on Fri May 17 2024 19:36:49 GMT+0200 (Central European Summer Time)
// by running `wrangler types`

interface Env {
SUBGRAPH_ENDPOINT: "https://gateway-arbitrum.network.thegraph.com/api/subgraphs/id/DZz4kDTdmzWLWsV373w2bSmoar3umKKH9y82SUKr5qmp";
SUBGRAPH_ENDPOINT: "https://gateway-arbitrum.network.thegraph.com/api/25eb15e49c08702d60d90be66dd9a9a3/subgraphs/id/74z4nnW6cr62ox3fLFaD3muieJzMXJimi6EZsG52yChM";
API_KEY: string;
RATE_LIMITER: DurableObjectNamespace;
}
12 changes: 10 additions & 2 deletions examples/nodejs-cf-worker/wrangler.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#:schema node_modules/wrangler/config-schema.json
name = "nodejs-cf-worker"
name = "redirect-rate-limit-network-test"
main = "src/index.ts"
compatibility_date = "2024-05-12"

Expand All @@ -16,4 +16,12 @@ mode = "smart"

# Replace this with your subgraph endpoint
[vars]
SUBGRAPH_ENDPOINT = "https://gateway-arbitrum.network.thegraph.com/api/subgraphs/id/DZz4kDTdmzWLWsV373w2bSmoar3umKKH9y82SUKr5qmp"
SUBGRAPH_ENDPOINT = "https://gateway-arbitrum.network.thegraph.com/api/25eb15e49c08702d60d90be66dd9a9a3/subgraphs/id/74z4nnW6cr62ox3fLFaD3muieJzMXJimi6EZsG52yChM"

[[durable_objects.bindings]]
name = "RATE_LIMITER"
class_name = "RateLimiter"

[[migrations]]
tag = "v1"
new_classes = ["RateLimiter"]