animir / node-rate-limiter-flexible

Atomic counters and rate limiting tools. Limit resource access at any scale.
ISC License
3.04k stars 157 forks source link

RateLimiterDynamo - Error: Table is not created yet #269

Closed schwjustin closed 2 months ago

schwjustin commented 3 months ago

In my SST Ion project (SST Ion uses Pulumi) I am building an API with API Gateway v2, Lambda functions, and DynamoDB. I implemented the following code for rate-limiter-flexible but I keep getting Error: Table is not created yet when the table is for sure already created and accessible in the AWS console:

const rateLimiterTable = new sst.aws.Dynamo("RateLimiterTable", {
    fields: {
        key: "string",
    },
    primaryIndex: { hashKey: "key" },
    transform: {
        table: (args) => {
            args.billingMode = "PAY_PER_REQUEST";
        },
    },
});
const dynamoClient = new DynamoDB({
    region: "us-east-1",
    credentials: {
        accessKeyId: "****", // I'm using my actual accessKeyId
        secretAccessKey: "****",  // I'm using my actual secretAccessKey
    },
    endpoint: "https://dynamodb.us-east-1.amazonaws.com",
});

const globalRateLimiter = new RateLimiterDynamo({
    tableName: process.env.RATE_LIMITER_TABLE, // Resource.RateLimiterTable.name,
    points: DEFAULT_RATE_LIMITS.GLOBAL_PER_SECOND,
    duration: 1,
    storeClient: dynamoClient,
});

export async function applyRateLimits(ip: string, userId: string | null, key: string, options: RateLimitOptions): Promise<void> {
    console.log("process.env.RATE_LIMITER_TABLE", process.env.RATE_LIMITER_TABLE);

    const limits = [
        { key: `global:${ip}`, limiter: globalRateLimiter },
        {
            key: `${key}:ip:${ip}:per_second`,
            limiter: new RateLimiterDynamo({
                tableName: Resource.RateLimiterTable.name,
                points: options.endpointLimits.perSecond || DEFAULT_RATE_LIMITS.IP_PER_SECOND,
                duration: 1,
                storeClient: dynamoClient,
            }),
        },

At some point I got a different error Error Cannot describe time to live while table is in CREATING state: Current table state is CREATING

animir commented 3 months ago

@schwjustin Hi, what is Resource variable in this line tableName: Resource.RateLimiterTable.name, ? What is Resource.RateLimiterTable.name value?

schwjustin commented 2 months ago

@animir sorry for the delay, I'm using sst ion and I can reference my aws (or other) resources through import { Resource } from "sst". This is my dynamo table:

const rateLimiterTable = new sst.aws.Dynamo("RateLimiterTable", {
    fields: {
        key: "string",
    },
    primaryIndex: { hashKey: "key" },
    transform: {
        table: (args) => {
            args.billingMode = "PAY_PER_REQUEST";
        },
    },
});
schwjustin commented 2 months ago

@animir Resource.RateLimiterTable.name prints: sst-justinschwartz-RateLimiterTableTable

schwjustin commented 2 months ago

Screenshot 2024-07-17 at 6 54 50 PM This is what I see in the aws console

animir commented 2 months ago

@schwjustin If you have that table created already, could you try setting tableCreated option to true when you create a limiter? This is the option description https://github.com/animir/node-rate-limiter-flexible/wiki/Options#tablecreated

That limiter options would be:

           {
                tableName: Resource.RateLimiterTable.name,
                tableCreated: true,
                points: options.endpointLimits.perSecond || DEFAULT_RATE_LIMITS.IP_PER_SECOND,
                duration: 1,
                storeClient: dynamoClient,
            }
schwjustin commented 2 months ago

That worked!