Использовать zerorpc внутри Flask-приложения выдает ошибку "операция блокируется навсегда" - PullRequest
0 голосов
/ 22 мая 2019

У меня RPC-сервер, использующий zerorpc в Python, написанный таким образом

import zerorpc
from service import Service

print('RPC server - loading')
def main():
    print('RPC server - main')
    s = zerorpc.Server(Service())
    s.bind("tcp://*:4242")
    s.run()

if __name__ == "__main__" : main()

Работает нормально при создании клиента

import zerorpc, sys

client_rpc = zerorpc.Client()
client_rpc.connect("tcp://127.0.0.1:4242")
name = sys.argv[1] if len(sys.argv) > 1 else "dude"
print(client_rpc.videos('138cd9e5-3c4c-488a-9b6f-49907b55a040.webm'))

и запускает его. Print () выводит то, что возвращает эта функция 'videos'.

Но когда я пытаюсь использовать этот же код внутри маршрута из приложения Flask, я получаю следующую ошибку:

Файл "src / gevent / __ greenlet_primitives.pxd", строка 35, в GEvent .__ greenlet_primitives._greenlet_switch gevent.exceptions.LoopExit: эта операция навсегда заблокирует Hub:

Метод колбы / выдержка

import zerorpc, sys

client_rpc = zerorpc.Client()
client_rpc.connect("tcp://127.0.0.1:4242")

@app.route('/videos', methods=['POST'])
def videos():

    global client_rpc
    client_rpc.videos('138cd9e5-3c4c-488a-9b6f-49907b55a040.webm')

Я не могу выяснить, что может происходить. Я новичок в Python и понимаю, что это может иметь какое-то отношение к Flask и тому, как он обрабатывает поток, но я не могу понять, как его решить.

1 Ответ

0 голосов
/ 22 мая 2019

zerorpc зависит от gevent, который обеспечивает асинхронный ввод-вывод с совместными сопрограммами. Это означает, что ваше приложение колбы должно использовать gevent для всех операций ввода-вывода.

В вашем конкретном случае вы, скорее всего, запускаете свое приложение со стандартным блокирующим IO WSGI-сервером.

Вот фрагмент кода, использующий сервер WSGI из gevent:

import zerorpc
from gevent.pywsgi import WSGIServer

app = Flask(__name__)

client_rpc = zerorpc.Client()
client_rpc.connect("tcp://127.0.0.1:4242")

@app.route('/videos', methods=['POST'])
def videos():
    global client_rpc
    client_rpc.videos('138cd9e5-3c4c-488a-9b6f-49907b55a040.webm')

# ...

if __name__ == "__main__":
    http = WSGIServer(('', 5000), app)
    http.serve_forever()

Выдержка из https://sdiehl.github.io/gevent-tutorial/#chat-server

...