I'm trying to build a script that runs asynchronously while having a start/stop mechanism based on user input from stdin.
I created two threads, one for the asynchronous work and one for reading from stdin. My idea is that the program runs until the user types "stop" in stdin, and the asynchronous tasks wait until the user types "start" in stdin.
Here is my current code:
class DataManager(metaclass=Singleton):
def __init__(self):
self.flag = threading.Event()
self.flag.set()
# Thread for reading user input
self.pool_thread = threading.Thread(target=self.__pool_input())
self.pool_thread.daemon = True
self.pool_thread.start()
# Method to create thread for asynchronous tasks
def start(self):
if self.flag.is_set():
self.flag.clear()
self.main_thread = threading.Thread(target=self.__main_wrapper)
self.main_thread.start()
# Method for reading user stdin
def __pool_input(self):
val = input()
if val == "stop":
self.stop()
elif val == "start":
self.start()
# Wrapper method to start the event loop and call async context
def __main_wrapper(self):
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(self.__main())
loop.close()
# Main async loop
async def __main(self):
while not self.flag.is_set():
# Run async stuff
# ...
print('Thread is running')
await asyncio.sleep(5)
# Stop the main async loop on user command
def stop(self):
if not self.flag.is_set():
self.flag.set()
if __name__ == "__main__":
data_manager = DataManager()
data_manager.start()
Expected behavior
- Async (main) thread runs on loop
- User types "stop" and async thread stops
- User types "start" and async loop runs again
Current behavior
- Async thread is blocked until user types on stdin
- Async thread starts running
- Stdin is blocked while async thread runs
Besides having to keep the __pool_input
thread active in some way (because once it reads the input once the thread ends and I never start it again) I don't know how to make the desired outcome work.