Skip to content

[FEATURE] Customizing concurrent handling of updates #3509

@Bibo-Joshi

Description

@Bibo-Joshi

What kind of feature are you missing? Where do you notice a shortcoming of PTB?

Setting ApplicationBuilder.concurrent_updates(True) allows to process all updates concurrently (up to a specified number at a time). What you can't do is e.g. processing updates from all users & chats concurrently while processing the updates for each user/chat sequentially. Having the possibility for such a mechanism would e.g. allow to

  • handle updates concurrently except those that are revelant for stateful handlers such as ConversationHandler
  • apply a rate-limiting mechanism for users by delaying processing of their updates
  • prioritizing certain types of updates for handling, e.g. inline/callback queries over regular messages

Describe the solution you'd like

  1. Introduce an interface class BaseThrottler (other naming suggestions are welcome!). This class should
    1. accept an integer that specifies the maximum overall number of updates that may be processed concurrently
    2. have a single abstract method async def process_update(update, coroutine) whose task it is to await at an appropriate time, that may be determined depending on the update
    3. have a single non-abstract method asyne def do_process_update that calls process_update after applying a global semaphore, which enforces the limit in a.
  2. Introduce a class SimpleThrottler(BaseThrottler) (other naming suggestions are welcome) for which process_update immediately awaits the coroutine, i.e. does not apply any additional throttling
  3. The behavior of Application.concurrent_updates(…) should be as follows:
    1. passing an int will make use of the SimpleThrottler with the respective max overall number of concurrent updates
    2. passing True will behave as a. with the current default number specified for that case
    3. passing an instace of BaseThrottler will use that instance for handling concurrency
  4. Application.concurrent_updates should return the max overall number of concurrent updates as specified for the throttler in use. The throttler itself may be made available via an additional attribute/property

Describe alternatives you've considered

  • Instead of an interface class, one could directly provide the SimpleThrottler and encourage users to override process_update
  • One could make SimpleThrottler a bit more elaborate by e.g. allowing to sequencify the processing of updates per chat id. In this case, I would vote to go for the interface-class approach as the implementation would surely require more elaborate internals than that of SimpleThrottler.

Additional context

This idea was already discussed a bit in the early stages of the v20 architecture design but was put on hold, since we first wanted to get the basic structure ready before introducing additional functionality.

Before an attempt on an implementation for this is made, I'd like to get feedback on the idea :)

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions