D
D
Denis2020-08-16 02:35:17
Python
Denis, 2020-08-16 02:35:17

How to stop asyncio server.serve_forever() from another thread?

There are 2 streams. In one, signals are caught (and a lot more, but this is all superfluous for the question), and in the other, server.serve_forever () occurs:

import sys
import signal
import asyncio
from threading import Thread

class Server:
    def run_serve(self):  # функция потока
        asyncio.run(self.serve())

    async def serve(self):  # функция запуска сервера, вызывается асинхронно в потоке
        self.server = await asyncio.start_server(self.handle_connection, '0.0.0.0', 5050)
        async with self.server:
            await self.server.serve_forever()

    async def handle_connection(self, reader, writer):  # просто эхо-заглушка принятия соединения
        while True:
            data = await reader.read(2048)
            writer.write(data)

    def close(self):  # должна закрыть self.server и завершить выполнение потока (функции run_serve)
        self.server.close()  # Работает только со второго раза, принудительным завершением

# Функция обработчика
def signal_handler(signal, frame):
    server.close()
    sys.exit(0)

# Обработчик
signal.signal(signal.SIGINT, signal_handler)

# Запускаем сервер
server = Server()
thread = Thread(target=server.run_serve)
thread.start()

while True:
    pass  # здесь что-то происходит


How to gracefully shut down the server and asyncio.run()? Can this be done at all? I tried to stop the loop itself, getting it in that stream. It didn't work out. Help please, I want to figure it out, maybe I built everything incorrectly and need it differently? But I have multiple instances of the Server class running, i.e. several streams, so I think there is no other way

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
Vladimir Olohtonov, 2020-08-16
@igudo

There is only one correct way to stop a thread from outside - to cock some flag, which the thread will look at in its main loop and stop itself.
Why do you need many threads with asyncio? They generally do not mix well, and they bring little profit, because the wait is already asynchronous, and computational operations basically keep the GIL.
If you still need it, then why not use the ThreadPoolExecutor?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question