-
Notifications
You must be signed in to change notification settings - Fork 5
time_bucketed.py not deadlock safe #1
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
Comments
Hi @mbaader , sorry for my late response! Your solution looks good, and the problem raised by your tests is something worth analyzing deeper. Just a doubt, could it be possible (and simpler) to delete the key if its value is negative? bucket_val = r.get(key)
if bucket_val and int(bucket_val) > 0:
val = r.decrby(key, 1)
if val < 0:
r.del(key)
return False (can't have any chance to test it sorry, not available pc atm) |
Hi astagi, yes, that might resolve the deadlock issue. But I'm not sure, if it addresses the race condition correctly. At least in theory, there might be any number of changes between the r.get(key) and the r.decrby(key, 1) so that an unexpected high number of tokens could be granted. That might have happend in the first part of my above code too, so I modified it to:
I've been using this code in production for a few weeks now and haven't had any issues with it yet. Regards |
That's cool @mbaader! (sorry again for my late response).. could you open a PR for that? I'll update the article accordingly |
ok @astagi - done. |
Hi there,
thank you very much for your time_bucketed.py code. And special thanks to the idea of using some kind of "icons" in the print messages. Didn't know that was possible, but I like it very much.
However, there are some issues that led to two deadlocks within an hour while I tested it:
If the key expires between GET and DECRBY, you'll generate a new key with value -1 but no associated expire (hence, the key will never expire). And because you use SETNX to create a key, you'll never create a new key with an associated expire, if there already is one without an associated expire :
Furthermore if other processes already decreased the value of that key to 0 between the GET and DECRBY, you might exceed the rate limit in this timeframe.
So I came up with this solution, that should address both issues:
Regards
Mat
The text was updated successfully, but these errors were encountered: