-
|
Hello. nested_registration_handler = ConversationHandler(
entry_points=[
CallbackQueryHandler(handle_registration_consent_agree, pattern=utils.generate_pattern_for_enum(keyboards.AgreeDisagree)),
],
states={
# Some states skipped
# ...
},
fallbacks=[
CommandHandler("cancel", handle_nested_registration_cancel),
],
map_to_parent={
ConversationHandler.END: ConversationHandler.END,
}
)
# Main account menu handler
account_handler = ConversationHandler(
entry_points=[
CommandHandler("account", handle_enter_account_menu)
],
states={
# some states skipped
# ...
ACCOUNT_MENU_START_REGISTRATION: [
nested_registration_handler,
],
},
fallbacks=[
CommandHandler("cancel", handle_account_menu_cancel),
],
)
For each of the handlers, I create a separate ChatHelper object that performs various auxiliary tasks and is stored in user_data. When each handler ends, I want to clear its ChatHelper. Also, when the nested_registration_handler is cancelled, I want to cancel the account_handler. So in the case of processing the /cancel command both ChatHelpers should be removed. At the same time, I want each handler to manage its own ChatHelper—to reduce confusion. I’ve encountered a problem where I can’t come up with a simple way to do this. For example, I’m currently trying the following solution for handling the /cancel command: nested_registration_handler = ConversationHandler(
entry_points=[
CallbackQueryHandler(handle_registration_consent_agree, pattern=utils.generate_pattern_for_enum(keyboards.AgreeDisagree)),
],
states={
# Some states skipped
# ...
},
fallbacks=[
CommandHandler("cancel", handle_nested_registration_cancel),
],
map_to_parent={
ConversationHandler.END: ConversationHandler.END,
9999: 9999,
}
)
# Main account menu handler
account_handler = ConversationHandler(
entry_points=[
CommandHandler("account", handle_enter_account_menu)
],
states={
# some states skipped
# ...
ACCOUNT_MENU_START_REGISTRATION: [
nested_registration_handler,
],
9999: [
CommandHandler("cancel", handle_account_menu_cancel),
]
},
fallbacks=[
CommandHandler("cancel", handle_account_menu_cancel),
],
)
That is, a special state 9999 was added. The nested_registration_handler intercepts the /cancel command, processes it, and returns control to the parent account_handler, transitioning it to state 9999. To ensure that handle_account_menu_cancel is triggered immediately, I have to do await context.update_queue.put(update) in the nested_registration_handler. And here, actually, are my questions:
|
Beta Was this translation helpful? Give feedback.
-
|
Hey! Also, when the nested_registration_handler is cancelled, I want to cancel the account_handler. An alternative from your current appraoch, is to clear the keys from user_data relevant to both conversations, in the nested /cancel handler. In theory, such a construction won't work if there is more than one update in the queue, TL;DR It can still work By default a conversation state is tracked by both chat.id and user.id. So a single CH instances will be book keeping many current active states, where each is sored under a key like (chat.id, user.id). See What do the per_* settings in ConversationHandler do?. Then, because then the next update in the queue for the account_handler may not necessarily be the current update with the /cancel command. True. However the parent conversation will already be at the 999 state. if that state only contains the cancel handler, then this next update will not pass the check and be ignored. This also assumes updates are handled sequentially. Having concurrency enabled (see Concurrency in PTB) might cause race conditions. from 10 different users. Then the first update will switch the handler to a state where the remaining updates cannot be processed until the handler returns to its initial state. Reply to previous points address this (for reference What do the per_* settings in ConversationHandler do?) Does this mean each update will wait for the previous ones to be processed? Whether updates will be processed sequentially or concurrently (Concurrency in PTB) is actually unrelated to how ConversationHandler will keep track of its active state(s) (What do the per_* settings in ConversationHandler do?). |
Beta Was this translation helpful? Give feedback.
Hey!
An update will be handled by a maximum of only one handler per group (see application.add_handler). And since both the nested and parent conversations are added in the same group, then a one unique message update with (/cancel) will be handled by either the nested cancel handler or the parent one, not both.
Also, when the nested_registration_handler is cancelled, I want to cancel the account_handler.
An alternative from your current appraoch, is to clear the keys from user_data relevant to both conversations, in the nested /cancel handler.
In theory, such a construction won't work if there is more than one update in the queue,
TL;DR It can still work
By default a conversation sta…