★ wanayoo — archive 1999 https://github.com/pyrogram/pyrogram/issues/182Nouvelle recherche | Portail wanayoo
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

Method calls rate limiter #182

Open
andreportela opened this issue Dec 21, 2018 · 7 comments
Open

Method calls rate limiter #182

andreportela opened this issue Dec 21, 2018 · 7 comments

Comments

@andreportela
Copy link

@andreportela andreportela commented Dec 21, 2018

I couldn't find a feature to throttle the bot message rate so you can avoid the 429's from the API SPAM limits.
PTB has this feature. I'm not sure if it's the best approach but it seems very useful for larger bots.
Is there a native way that I can do that using Pyrogram?

@delivrance
Copy link
Member

@delivrance delivrance commented Dec 21, 2018

@andreportela Hi. No, currently there's nothing like a message queue as in ptb.
What you can do is wrap your method calls in a try..except block, catch FloodWait errors and get the amount of seconds needed to wait before you can try again, then you can either sleep or deny any further calls until the timeout expires.

Example

...
try:
    app.send_message(...)
except FloodWait as e:
    time.sleep(e.x)  # e.x contains the flood wait timeout
@andreportela
Copy link
Author

@andreportela andreportela commented Dec 21, 2018

Got it. Thanks for the quick answer!!

I think this type of feature has such a great potential. It may remove boilerplate, keep things cleaner and simpler.

What do you think about including this kind of feature?

@delivrance
Copy link
Member

@delivrance delivrance commented Dec 21, 2018

@andreportela It can probably help, somehow, but it must also be noted that implementing anything that helps avoiding flood wait errors is almost pointless in an MTProto library such as Pyrogram:

  • First of all, limits are practically unknown; in fact, the 30 msgs/sec on users and the 20 msgs/min/group limit is all we know (for bots). A rate limiter will basically have to deal with only these known limits.
  • Normal bots and users have different limits, and while the bot limits are somewhat "documented", there's no documentation that hints about the limits on users.
  • They are different between the whole plethora of API methods (send_message, kick_chat_user, delete_message, etc...), and for each method the rate also differs depending on which arguments you pass (e.g.: you might be limited in messaging user X with message M, but likely not limited to message user Y with the same message M).
  • They can change without any notice.
@delivrance
Copy link
Member

@delivrance delivrance commented Dec 21, 2018

Now that I think about, what I said previously makes sense in case one wants to completely avoid flood waits. A simpler rate limiter that works globally could be one that caches method calls with all of their arguments and starts denying the next same calls in case a first flood wait was received, until the timeout expires.

@andreportela
Copy link
Author

@andreportela andreportela commented Dec 21, 2018

That would be one choice. Another one would be to queue those messages and dispatching them in a given rate. I think one doesn't need to exclude the other.

Simple constructs like this can be flexibly used by many people. 😀

@delivrance
Copy link
Member

@delivrance delivrance commented Dec 23, 2018

@andreportela Again, the rate at which the queued messages will be sent can't be assumed because it's still probable to get a flood wait, or worse, introduce delays.
People will probably start to complain about why messages are not sent immediately.

@delivrance delivrance changed the title Question: message rate limit Method calls rate limiter Dec 23, 2018
@fgallaire
Copy link
Contributor

@fgallaire fgallaire commented Jun 3, 2020

Example

...
try:
    app.send_message(...)
except FloodWait as e:
    time.sleep(e.x)  # e.x contains the flood wait timeout

@delivrance, thanks for your great software and explanations. IMHO this example needs to be improved to help people: as the code catched by the exception has failed due to the flood limitation, it needs to be repeated.

Fixed example proposition

...
try:
    app.send_message(...)
except FloodWait as e:
    time.sleep(e.x)  # e.x contains the flood wait timeout
    app.send_message(...) # repeat catched code

The documentation could be improved here:
https://docs.pyrogram.org/faq#how-can-avoid-flood-waits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.