#asynchronous #tornado
#асинхронный #tornado
Вопрос:
У меня есть два микросервиса:
- служба
Служба Tornado с двумя конечными точками: /foo
и /bar
/foo
async def get(...):
x = await test()
return x
async def test():
y = call to b service, FooBar rpc
return y
/bar
def get(...):
return True
- служба b
Служба gRPC с rpc FooBar
rpc FooBar
def FooBar(...):
return requests.get("/bar")
Если клиент попадает в конечную /foo
точку в службе:
- Код попадает в rpc FooBar в службе b.
- FooBar rpc не может попасть
/bar
в конечную точку службы, поскольку эта служба заблокирована.
AFAIK, использование x= await test() должно предотвратить такую блокировку, что я пропустил?
Комментарии:
1.
await
автоматически не делает ваш код неблокирующим. Являются ли эти вызовы rpc асинхронными? Если нет, то это вызовет блокировку.2. @xyres да, вызов rpc является синхронным. Но проблема в том, что служба tornado заблокирована, а не служба grpc
3. Да, если вызовы rpc не являются асинхронными, они заблокируют процесс tornado (потому что вы выполняете эти вызовы из процесса tornado).
4. @xyres нет способа «обойти» его с помощью вызова rpc sync?
Ответ №1:
Поскольку вызовы rpc не являются асинхронными, это заблокирует процесс Tornado.
Вы можете избежать блокировки основного процесса, запустив вызовы rpc в отдельном потоке.
Во-первых, сделайте test()
метод обычной функцией, а не сопрограммой (удалите async
ключевое слово).
Пример кода:
async def get(...):
x = await IOLoop.current().run_in_executor(None, test)
return x
# regular function, not async
def test(...):
# make calls
return x