Returning Unused Tokens
Closed this issue · 4 comments
I've been utilizing redis-cell for a research project and first and foremost thank you for your work.
I'm in a situation where I want to all or nothing check two different keys that can be throttled. I need to check one, have it pass then check the other and have it also pass before I approve the action. I perform the entire atomic operation via a LUA script.
In the event the second key cl.throttle returns 1 (throttled), is it appropriate to return the first via:
cl.throttle key burst max period -1
Preliminary tests seem to indicate this works, but I'm unsure if this was intentional. Is there a potential fringe case where this would fail or un-optimize key usage?
In the event the second key cl.throttle returns 1 (throttled), is it appropriate to return the first via:
Hm, just to make sure I understand this correctly: if you're just trying to return the result of the first cl.throttle
invocation, couldn't you just set that as a variable when it's called and then return that later?
ret1 = cl.throttle ...
ret2 = cl.throttle ...
if ret2 == 1
return ret1
end
(Or something to that effect.)
Sure, but the token is still consumed from the first bucket since it passed, correct? I don't want the first token consumed if the second one fails.
I put water in the first bucket, then water in the second bucket. If I can't put water in the second bucket, then I want to take the water I put into the first bucket out.
Essentially I want to undo ever calling ret1 = cl.throttle ...
if ret2 ==1
. Or maybe I can fork this and create a cl.peek
to check what cl.throttle
would return without consuming a token. Maybe this can be done already by asking for 0
tokens instead of the default 1
?
Ah, I see.
Well, the calculation to get a new value when cl.throttle
is called is really just basic multiplication and it uses signed numbers all the way through. If it looks like it works by just using a negative value, then that's probably fine to do.
Essentially I want to undo ever calling ret1 = cl.throttle ... if ret2 ==1. Or maybe I can fork this and create a cl.peek to check what cl.throttle would return without consuming a token. Maybe this can be done already by asking for 0 tokens instead of the default 1?
One other alternative is that you can peek today by just passing 0
as the last argument. This case is actually verified in the test suite:
// Zero-volume request just peeks at the state.
RateLimitCase::new(12, start + time::Duration::milliseconds(9500), 0, 4,
time::Duration::seconds(1), time::Duration::seconds(-1), false),
This is perfect then. Since Redis guarantees atomicity during a LUA script, I could peek at both buckets and make a decision there.
Thank you for the quick responses.