Инкрементальный процесс Gevent через неблокирующую joinall () - PullRequest
0 голосов
/ 09 ноября 2011

Здесь я хочу сделать некоторые модификации для моих настроек.

Я хочу получить ответ от нескольких вызовов API в рамках одного запроса к моему серверу. Из всех этих вызовов API я хочу объединить результаты и вернуть их в ответ. До тех пор, пока здесь, почти все не следует, как указано в примерах документации Gevent и здесь. Теперь уловка в том, что я хочу передать ответ инкрементно, поэтому, если первый вызов API вернул результат, я верну этот результат интерфейсу в одном долгожданном запросе, а затем дождусь других вызовов API и передам их в том же запросе внешний интерфейс.

Я пытался сделать это с помощью кода, но я не знаю, как выполнить эту настройку. Блок gevent .joinall() и .join() пока все гринлеты не закончат получать ответы.

Как я могу продолжить с gevent в этой настройке?

Код, который я здесь использую, приведен по ссылке https://bitbucket.org/denis/gevent/src/tip/examples/concurrent_download.py. Здесь .joinall() в последнем выражении ожидает, пока все URL не дадут полных ответов, я хочу, чтобы он был неблокирующим, чтобы я мог обрабатывать ответы в функции обратного вызова print_head () и возвращать их постепенно.

#!/usr/bin/python
# Copyright (c) 2009 Denis Bilenko. See LICENSE for details.

"""Spawn multiple workers and wait for them to complete"""

urls = ['http://www.google.com', 'http://www.yandex.ru', 'http://www.python.org']

import gevent
from gevent import monkey

# patches stdlib (including socket and ssl modules) to cooperate with other greenlets
monkey.patch_all()

import urllib2


def print_head(url):
    print ('Starting %s' % url)
    data = urllib2.urlopen(url).read()
    print ('%s: %s bytes: %r' % (url, len(data), data[:50]))

jobs = [gevent.spawn(print_head, url) for url in urls]

gevent.joinall(jobs)

1 Ответ

1 голос
/ 09 ноября 2011

Если вы хотите собрать результаты из нескольких гринлетов, измените print_head(), чтобы вернуть результат, а затем используйте метод .get(), чтобы собрать их все.

Поставьте это после joinall():

total_result = [x.get() for x in jobs]

На самом деле, joinall() даже не требуется в этом случае.

Если print_head() выглядит так:

def print_head(url):
    print ('Starting %s' % url)
    return urllib2.urlopen(url).read()

Тогда total_result будет спискомразмером 3, содержащий ответы на все запросы.

...