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

throttle: add support for Redis installs without redis-cell module #282

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

djc
Copy link
Contributor

@djc djc commented Sep 18, 2024

Uses a Lua script for GCRA from https://github.com/Losant/redis-gcra/blob/master/lib/gcra.lua to perform the necessary logic without support for the redis-cell module that provides CL.THROTTLE.

Fixes #275.

Copy link
Contributor Author

@djc djc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This hasn't seen any testing, just pushing up my current state for possible feedback.

crates/throttle/src/throttle.rs Show resolved Hide resolved
crates/throttle/src/throttle.rs Outdated Show resolved Hide resolved
crates/throttle/src/throttle.rs Outdated Show resolved Hide resolved
@djc djc force-pushed the redis-gcra branch 2 times, most recently from 918c6a5 to 1bab348 Compare September 19, 2024 12:28
crates/throttle/src/throttle.rs Outdated Show resolved Hide resolved
crates/throttle/src/throttle.rs Outdated Show resolved Hide resolved
crates/throttle/src/lib.rs Show resolved Hide resolved
crates/throttle/src/lib.rs Outdated Show resolved Hide resolved
@djc djc force-pushed the redis-gcra branch 2 times, most recently from 1cce908 to fc95611 Compare September 19, 2024 14:11
@djc djc marked this pull request as ready for review September 19, 2024 14:11
@djc
Copy link
Contributor Author

djc commented Sep 19, 2024

@wez the new test now passes which leads me to think this is probably done? Let me know if you want to see more test coverage.

crates/throttle/src/throttle.rs Outdated Show resolved Hide resolved
remaining: result.1,
reset_after: Duration::from_secs(result.2),
retry_after: match result.3 {
0 => None,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the redis_cell_throttle implementation of this above handles the case where the number is negative, and also has a different representation for 0.

Which is right? TBH, I think neither is quite right!

The logic that consumes the throttles assumes that if retry_after.is_some(), then we were throttled, and will break out of the throttle checking loop otherwise. It's probably best to formally encode that here for the various implementations and ensure that this is None if we are not throttled, and otherwise set this to the returned interval, clamping negative values to 0 so that we can't panic or return overflown/wrapped unsigned durations for this case.

I confess to not knowing whether it is possible to get a 0 second result here if we are throttled. That might be an awkward edge case that produces some busier looping in the consumer, so I'm open to considering clamping to a minimum of 1 second in the throttled case.

What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I noticed that ThrottleResult::retry_after is actually the only field from that type that gets used outside the crate. Should we just get rid of everything else?

Will dig more into the details of this tomorrow, my brain is a little too fried to go deep on this now.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

preserving the other fields seems useful to me, if for example, we wanted to have those automatically translate into the conventional set of http throttling headers in the response to an http request.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the script throttle, retry_after has math.ceil() applied to it, so I don't think it can return 0 when throttling happens (in that case diff must be non-zero because remaining is not 0). I think that also means it's always more than 0 in the throttled case. I've made the code a bit more similar to the redis_cell_throttle().

Not sure what else to do here? Feel free to make changes to the PR if you just want to get it merged.

@djc djc force-pushed the redis-gcra branch 2 times, most recently from b5e5b76 to 5fa5a6d Compare September 20, 2024 15:15
Copy link
Collaborator

@wez wez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there's an issue with running make test

@@ -215,15 +215,15 @@ impl TryFrom<&str> for ThrottleSpec {
#[derive(Debug, Eq, PartialEq, Serialize)]
pub struct ThrottleResult {
/// true if the action was limited
pub throttled: bool,
pub(crate) throttled: bool,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to keep these in the public interface for future use

@djc
Copy link
Contributor Author

djc commented Sep 21, 2024

Looks like there's an issue with running make test

You mean this, right?

Screenshot 2024-09-21 at 08 56 01

This confuses since I have a commit that should address this ("mod-redis: derive Debug for RedisConnection").

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Introduce alternate throttle implementation that doesn't use redis-cell
2 participants