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

Question about precise-memory-ratelimit #316

Open
Nebulizer1213 opened this issue Aug 5, 2022 · 6 comments
Open

Question about precise-memory-ratelimit #316

Nebulizer1213 opened this issue Aug 5, 2022 · 6 comments
Labels
external-store Related to external stores question A question related to the library

Comments

@Nebulizer1213
Copy link

Nebulizer1213 commented Aug 5, 2022

Description

Is there a way to get the request and response from inside of the increment function, so I can get the max if they use the ValueDeterminingMiddleWare?

I have this, but it only works if they use a number for max

        let user = this.hits[key]
        let reset = calculateNextResetTime(this.windowMs, user)
        if (user.ts + this.windowMs <= time()) {
            user.hits = 0
        }
        if (user.hits > this.max) {
            return {
                totalHits: user.hits,
                resetTime: reset
            }
        }
        user.hits++
        user.ts = time()
        this.hits[key] = user
        return {
            totalHits: user.hits,
            resetTime: reset
        }

Library version

6.5.1

Node version

v18.4.0

Typescript version (if you are using it)

v4.7.4

Module system

ESM

@Nebulizer1213 Nebulizer1213 added the bug A bug in the library label Aug 5, 2022
@gamemaker1
Copy link
Member

You could get the max (function or number) from the options passed in the init function:

So in your init function you could add the following line:

const getMax = typeof options.max === 'function'
	? options.max(request, response)
	: options.max
this.max = await getMax

And then remove the same line from your constructor.

@gamemaker1 gamemaker1 added question A question related to the library external-store Related to external stores and removed bug A bug in the library labels Aug 5, 2022
@nfriedly
Copy link
Member

nfriedly commented Aug 5, 2022

@gamemaker1 I don't think that would work, as request and response aren't available when the init function is called.

@Nebulizer1213 I think this would require a change to the store API, to either pass in the request/response, or else the calculated max value in an extra argument. If we were going to pass in req/res, it would probably make sense to calculate max and set it on the req ahead of time. Let me think about that a bit more...

Can you give me more context on what ValueDeterminingMiddleWare is? Why would increment need to know the max value?

@Nebulizer1213
Copy link
Author

@nfriedly I need the max in the incr function because if the user's request exceeds the max, the timestamp for the user should not change.

    if (user.hits > this.max) {
            return {
                totalHits: user.hits,
                resetTime: reset
            }
        }
        user.hits++
        user.ts = time()

@nfriedly
Copy link
Member

nfriedly commented Aug 5, 2022

Hum.. it looks like the redis and mongo stores handle this via an option - the reset time is based either on the first hit or the most recent hit. I don't think any store counts the reset time from the last successful hit.

Would something like that work for your use-case?

@Nebulizer1213
Copy link
Author

I'm pretty sure the other stores use the fixed window algorithm by setting an expiry on the first request. This would not work for me because I use the token bucket algorithm.

@nfriedly
Copy link
Member

Ok, I've been thinking about this. I think we should just add max as an extra param on the end of the increment call. When max is a function, we should execute it within express-rate-limit and pass along the integer value, not the function.

I don't think this will break any existing stores, but I'd like to check to be sure. If necessary, we could add a way for stores to opt into this behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
external-store Related to external stores question A question related to the library
Projects
None yet
Development

No branches or pull requests

3 participants