Асинхронные вызовы Zerorpc

#python #asynchronous #zeromq #zerorpc

#python #асинхронный #zeromq #zerorpc

Вопрос:

Сервер

Предположим, у меня есть следующий сервер zerorpc

 #server side
import zerorpc

class API():

    def long_running_task(self):
        print('1 - started long_running_task')
        #for instance a long running SQL query
        zerorpc.gevent.sleep(10)
        print('2 - finished long_running_task')

    def other_task(self):
        print('1 - started other_task')
        pass
        print('2 - finished other_task')

s = zerorpc.Server(API())
s.bind("tcp://0.0.0.0:4444")
zerorpc.gevent.spawn(s.run)
while True:
    zerorpc.gevent.sleep(10)
  

Клиент

и клиентское приложение, которое отправляет несколько запросов одновременно

 import zerorpc

client = zerorpc.Client()
client.connect("tcp://127.0.0.1:4444")

client.long_running_task(async_=True)
client.other_task(async_=True)

client.close()
  

Проблема в том, что во время выполнения long_running_task other_task не запускается.

Желаемый результат:

 1 - started long_running_task
1 - started other_task
2 - finished other_task
2 - finished long_running_task
  

вместо

 1 - started long_running_task
2 - finished long_running_task
1 - started other_task
2 - finished other_task
  

Ответ №1:

Здесь есть несколько ошибок

  1. async_ должно быть async . Это гарантирует, что клиентский метод немедленно возвращается
  2. ZeroRPC работает с gevent. Итак, вам нужно запустить сервер с. gevent.spawn(s.run) Также для поддержания работы вашего основного гринлета.
 zerorpc.gevent.spawn(s.run)
while True:
     zerorpc.gevent.sleep(10)
  
  1. выше 2 недостаточно. В API() методах вы тоже должны сотрудничать. Вместо time.sleep() использования gevent.sleep() .

Комментарии:

1. Привет, спасибо за ответ, я отредактировал вопрос на основе пунктов 2 и 3. К пункту 1: проблема в том, что если я использую ключевое слово async, я получаю синтаксическую ошибку (у меня python 3.7). github.com/ansible/ansible/issues/32816 . После внесения изменений скрипт по-прежнему не выполняется должным образом..

2. async=True может быть записан как **{"async": True}

3. Я думал, что async был заменен на async_ в библиотеке, моя ошибка.. Спасибо за помощь!