通过非阻塞joinall()的Gevent增量过程

时间:2011-11-09 10:12:26

标签: python urllib gevent monkeypatching

这里我想为我的设置做一些修改。

我希望在向我的服务器发出的单个请求中响应多个API调用。在所有这些API调用中,我想组合结果并将它们作为响应返回。在这里,几乎所有内容都遵循gevent文档的示例以及此处。现在这里的问题是我想以增量方式传递响应,所以如果第一次API调用返回了结果,我将把这个结果返回到一个长等待请求的前端,然后等待其他API调用并将它们传递给同一个请求前端。

我试过通过代码执行此操作,但我不知道如何继续此设置。 gevent .joinall().join()阻止所有greenlet完成获取响应。

在这种情况下我可以用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 个答案:

答案 0 :(得分:1)

如果您想从多个greenlet收集结果,请修改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的列表,其中包含来自所有请求的响应。