Я смущен тем, как играть с модулем asyncio
в Python 3.4. Я использую API searching
для поисковой системы и хочу, чтобы каждый запрос на поиск выполнялся либо параллельно, либо асинхронно, так что мне не нужно ждать завершения одного поиска.
Вот мой высокоуровневый API поиска для создания некоторых объектов с необработанными результатами поиска. В самой поисковой системе используется какой-то механизм асинхронности, поэтому я не буду с этим документировать.
# No asyncio module used here now
class search(object):
...
self.s = some_search_engine()
...
def searching(self, *args, **kwargs):
ret = {}
# do some raw searching according to args and kwargs and build the wrapped results
...
return ret
Чтобы попытаться выполнить асинхронизацию запросов, я написал следующий тестовый пример, чтобы проверить, как я могу взаимодействовать с ним с помощью модуля asyncio
.
# Here is my testing script
@asyncio.coroutine
def handle(f, *args, **kwargs):
r = yield from f(*args, **kwargs)
return r
s = search()
loop = asyncio.get_event_loop()
loop.run_until_complete(handle(s.searching, arg1, arg2, ...))
loop.close()
Запустив pytest, он вернет RuntimeError: Task got bad yield : {results from searching...}
, когда он попадет на строку r = yield from ...
.
Я также пробовал по-другому.
# same handle as above
def handle(..):
....
s = search()
loop = asyncio.get_event_loop()
tasks = [
asyncio.async(handle(s.searching, arg11, arg12, ...)),
asyncio.async(handle(s.searching, arg21, arg22, ...)),
...
]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
Запустив этот тестовый файл с помощью pytest, он пройдет, но какое-то странное исключение из поисковой системы поднимет. И он говорит Future/Task exception was never retrieved
.
Вещи, которые я хочу задать:
- Для моей первой попытки, правильно ли использовать
yield from
, вернув фактический результат из вызова функции? - Я думаю, мне нужно добавить немного сна к моему 2-му тестовому примеру, чтобы дождаться завершения задачи, но как мне это сделать? И как я могу получить свои вызовы функций для возврата во втором тестовом случае?
- Это хороший способ реализовать asyncio с существующим модулем, создав обработчик async для обработки запросов?
- Если ответ на вопрос 2 НЕТ, каждый клиент вызывает класс
search
, должен включатьloop = get_event_loop()
этот тип материалов для асинхронизации запросов?