Reputation: 657
I have a process that should accept requests from two different sources. It is not important, what those requests are, consider them simple string messages for instance. Requests can come from two sources and are filed into a PriorityQueue
. The main process handles the requests in the queue. One of the two sources for requests is a telegram bot created by the python-telegram-bot
package. Every source needs to run its "event" loop to provide requests. Thus, I want to launch them in separate threads.
The (pseudo) code to show the intention would read as follows:
queue = PriorityQueue()
handler = RequestHandler(queue)
telegramRequester = TelegramRequester(queue)
anotherRequester = SomeOtherSourceRequester(queue)
telegramRequester.start() # launches telegram bot polling/idle loop
anotherRequester.start() # launches the loop of another request source
handler.handleRequestsLoop() # launches the loop that handles incoming requests
The telegram bot and corresponding requester look something like this:
class Bot:
def __init__(self):
self._updater = telegram.ext.Updater("my api token", use_context=True)
def run(self):
self._updater.start_polling(drop_pending_updates=True)
self._updater.idle()
def otherFunctions(self):
# like registering commands, command handlers etc.
# I've got my bot working and tested as I want it.
class TelegramRequester:
def __init__(self, queue:RequestQueue) -> None:
self._queue:RequestQueue = requestQueue
self._bot = Bot()
self._thread:threading.Thread = threading.Thread(target=self._bot.run)
def start(self):
if not self._thread.is_alive():
self._thread.start()
However, when running this, I receive the following error messsage:
File "...\myscript.py", line 83, in run
self._updater.idle()
File "...\env\lib\site-packages\telegram\ext\updater.py", line 885, in idle
signal(sig, self._signal_handler)
File "C:\Program Files\aaaProgrammieren\Python\Python3_9\lib\signal.py", line 47, in signal
handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler))
ValueError: signal only works in main thread of the main interpreter
It's the first time I use the telegram api and that I have multiple threads running in parallel. Plus, I have no experience in "web/network/etc." programming. Is it that simple? You shall not run a telegram bot in a separate thread! Or is there something very simple I am missing that would make a construct like mine possible?
Upvotes: 0
Views: 4032
Reputation: 148
you can't run bot multiple time, this will make a conflict.
.start_polling()
should run only one time, so i think when you make it in multi-threading you will get a conflict.
Upvotes: 0
Reputation: 7020
Just some general hints on the usage of PTB (v13.x) in this context:
Updater.idle()
is intended to keep the main thread alive - nothing else. This is because Updater.start_polling
starts a few background threads that do the actual work but don't prevent the main thread from ending. If you have multiple things going on in the main thread, you'll probably have a custom "keep alive" and "shutdown" logic, so you'll likely not need Updater.idle()
at all. Instead, you can just call Updater.stop()
when you want it to shut down.Updater.idle()
allows you to customize which signals it sets. You can pass an empty list to not set any signal handlers.Dislaimer: I'm currently the maintainer of PTB
Upvotes: 1