-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Bug: Throttler does not show correct token time until 1 token is available #5458
Comments
@rumpfc Thank you for reporting.
Why do you think so? |
Thanks! I sent a PR to fix it: #5463 |
I debugged through it 5 seconds after my last successful check. With a rate of 0.01/s and a token value of 0.87 I did the math to calculate when my token value is 1:
I compared that result with |
Do you say it shows 100, but if you wait for only 97 seconds, you get a token in reality? I think you should wait for 100 seconds or more. |
Exactly, the token is already available after 97 seconds, 3 seconds earlier then actually displayed. (Tried out with version 4.1.5) There is a game using a similar mechanism: Dota 2. Some skills have charges. The moment you don't have max. number of charges, a timer starts, showing when you get the next charge for your skill. I assume that CI throttler should work the same |
I see it more like pocket money for your children so that they can use it however they want. Every week/month they get a fixed amount, no matter if they still have it or already used it up. If the children ask you for more money now even though they would get their pocket money in 2 days anyway, would you say "No, and now you have to wait 30 days to get your next pocket money"? I'd tell them to wait patiently because they would get their fair amount regularly anyway. If you want to punish your users in that way, just change the parameters for |
@rumpfc Okay, you don't have needs to increase refresh time. |
Exactly. For me:
The current logic is a mix of both behaviors (your view and my view). This cannot work by a long shot. Either fix |
@rumpfc But I'm not sure what is tokenTime. What do you think of this? |
I want to quote from official CI4 manual about token time:
It seems you want that the token mechanism works like this: After the user used up all his tokens, he/she must wait xxx seconds to get a new set of tokens again. Imagine you have 3 tokens available which refreshes every 1 hour. You use 2 tokens (now having 1 left) and you do nothing for 55 minutes. Now he/she uses the final token (having no tokens left and 5 minutes before token refreshes). Do you still think the user should get no tokens for another 1 hour just because he/she wants to do something too early? |
@rumpfc Thank you for quoting. |
How about returning 0, -1 or null (making the return type nullable)? |
Changing the return type is a breaking change. |
Honestly I don't see the change from
0 or a negative number can mean
Depends on your definition. Just explain in the documentation the meaning of your return value. |
@rumpfc I think 0 is enough for now. 0 means you should not have got it, or it is not calculated. |
@kenjis don't forget to update the document. I think it still mentions "1" on |
@rumpfc Where in the document? |
In the User Guide and in PHPDoc at the method https://github.com/codeigniter4/userguide/blob/master/docs/libraries/throttler.html#L519 |
I don't get what you mean. |
@kenjis I see. |
PHP Version
8.0
CodeIgniter4 Version
4.1.5
CodeIgniter4 Installation Method
Composer (using
codeigniter4/appstarter
)Which operating systems have you tested for this bug?
Windows
Which server did you use?
cli-server (PHP built-in webserver)
Database
No response
What happened?
After some experiments with Throttler where I execute an action and get tokenTime returned after each action, I tackled some unexpected behaviour where I executed a successful action too early.
Example:
After some more experiments I realized that tokenTime is calculated using timestamp of last successful check instead of calculating when 1 token is available again.
Steps to Reproduce
Here is a unit test which uses a capacity of 2 and a refill timer of 200. This means
It measures the token time after doing following steps:
Here is the test output
Expected Output
Throttler::tokenTime
should return the remaining time until 1 token is available in case check failed.Anything else?
Looking at your source code, I saw that you don't use consistent time. Sometimes you use
time()
(php function) and sometimes you useThrottler::time()
(which uses either test time ortime()
from php). I tried above tests using$throttler-setTestTime(...)
, but got assertion errors not attokenTime
, but at the 2ndcheck
.The text was updated successfully, but these errors were encountered: