Сервер grpc немедленно завершает работу, если он работает вместе с приложением Flask с отслеживанием

Я пытаюсь запустить 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 по отдельности работают правильно, весь остальной код остается без изменений.

Как заставить сосуществовать эти два цикла событий?


person alexykot    schedule 29.05.2019    source источник


Ответы (1)


Что ж, переменная server будет удалена после завершения функции start_server. Вот почему сервер gRPC кажется сразу закрытым. Чтобы решить эту проблему, вы можете использовать глобальную переменную для хранения объекта сервера.

Кроме того, если вы считаете, что этот дизайн API не идеален, не стесняйтесь сообщать о проблеме в репозитории GitHub https://github.com/grpc/grpc.

person Lidi Zheng    schedule 04.06.2019