nikolaposa / rate-limit

🚔 General purpose rate limiter implementation.
MIT License
269 stars 47 forks source link

Know actual rate limit status #45

Open jeremiegrenier opened 3 years ago

jeremiegrenier commented 3 years ago

Hi,

Currently you can't get the actual rate limit status. Indeed, you only have the status after call to limit or limitSilently.

I think it could be great to have a method like getRateLimitStatus to know the actual state of limit, like the remainingAttemps.

We created a branch with this feature: see get-status-rate-limit

nikolaposa commented 3 years ago

What would be the benefit, use case for getRateLimitStatus()? I try to think of a rate limiter as a simple guard that either passes or fails, whereas detailed information contained that rate limit status provides is useful only for fail scenarios.

jeremiegrenier commented 3 years ago

It could be useful to give some details to user before the fails that he already have exceed limit.

When user start application, he could know if he already have exceed limit, the next date for new try, etc. And we do not want to try to "limit" since no actions are asked by user.

Our use-case:

We want to limit the number of email send by an user. And to be user-friendly, we want to display to user his actual rate limit before he perform any action.

BrianHenryIE commented 3 years ago

When using $status = $rateLimiter->limitSilently(), knowing how many requests have come from that IP during the interval informs what action to take.

First, thank you for the library. I've just used it yesterday and today to write a WordPress/WooCommerce plugin after a DOS attack via our payment processor – someone ran ~1200 fake cards into our checkout and our payment processor said "that's enough processing for today", cutting off our legitimate customers.

What I've built is: BH WC Checkout Rate Limiter where the main code using the rate limiting is in the AJAX class (i.e. when someone clicks "Place Order"). What I'm able to do with the returned Status class, I feel could be richer.

In this case, I'd like to use LogLevel::NOTICE for anyone who exceeds the threshold (then adjust up as reasonable), LogLevel::WARNING when the rate limits in an interval are exceeded more than usual, and LogLevel::ERROR which they're off the scale!

Adding $current to Status seems sensible. It looks like it could be done as a non-breaking change too.

Aside, for my usage of the library, I wanted to use it in WordPress, so I found a library that implemented WordPress's transient cache (thus object cache) in PSR-16, then wrote a PSR-16 layer. The WordPress implementation then was just a constructor feeding wp-oop/transient-cache. Please take a look and let me know have I missed anything, if not I'll make a PR: Psr16RateLimiter.php

nikolaposa commented 3 years ago

Thank you very much @BrianHenryIE 👍🏻

Adding $current to Status seems sensible. It looks like it could be done as a non-breaking change too.

@jeremiegrenier Would something like this meet your needs as well?

I found a library that implemented WordPress's transient cache (thus object cache) in PSR-16

This seems promising, PSR-16 rate limit back-end could be an interesting idea. I'll be happy to consider and review a PR for that.