Я пытаюсь запустить Flask REST API и gRPC API внутри одного приложения и контейнера, и по какой-то причине сервер gRPC закрывается сразу после запуска.
Итак, у меня есть простое приложение Flask, обслуживающее несколько конечных точек REST. У него есть два чертежа и бутстрапа с довольно стандартной точкой входа:
#!/usr/bin/env python
from app import bootstrap
app_name = os.environ.get(C.KEYS.APP_NAME_KEY)
conf_data = bootstrap.get_conf_data(app_name)
flask_app = bootstrap.get_app(app_name, conf_data)
bootstrap.register_blueprints(flask_app)
if __name__ == '__main__':
flask_app.run()
Я создал отдельный модуль, реализующий простой интерфейс gRPC, и хочу запускать оба одновременно на разных портах внутри одного приложения и контейнера. Реализация сервера gRPC по умолчанию использует futures.ThreadPoolExecutor
и не блокируется, поэтому я предполагаю, что он должен работать в фоновом режиме выполнения приложения Flask. Начальная загрузка сервера gRPC выглядит так:
import grpc
from concurrent import futures
from svc.auth_grpc import auth_pb2, auth_pb2_grpc
def start_server():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=1),
maximum_concurrent_rpcs=1)
auth_pb2_grpc.add_AuthServiceServicer_to_server(AuthServiceServicer(),
server)
server.add_insecure_port(f'0.0.0.0:9091')
server.start()
И поскольку моя цель - совместить gRPC и Flask, я добавляю загрузку gRPC в точку входа приложения следующим образом:
if __name__ == '__main__':
start_server()
flask_app.run()
Я ожидаю, что gRPC запустит поток и будет жить в фоновом режиме неопределенно долго, а Flask выполнит стандартную блокирующую загрузку werkzeug и будет жить на переднем плане. Все это происходит в начале, однако в следующую секунду после запуска Flask очередь gRPC CompletionQueue
получает событие SHUTDOWN
, и сервер завершает работу.
Я не знаю, почему происходит это событие и что его вызывает, и я не могу углубиться в CompletionQueue
, потому что это реализация Cython внизу.
Сервер gRPC и приложение Flask по отдельности работают правильно, весь остальной код остается без изменений.
Как заставить сосуществовать эти два цикла событий?