2011-11-09 17 views
0

這裏我想對我的設置進行一些修改。通過非阻塞的gevent增量過程joinall()

我希望在對我的服務器發出的一個請求中發出多個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

如果你想收集來自多個greenlets結果,然後修改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的含所有請求的響應列表。

+0

我試着修改print_head()來返回結果,併爲作業列表中的每個作業做一個.get(),但問題仍然存在.get()塊,我可以使用非阻塞的東西,而不是相同的執行流程繼續監控每項工作的結果。 – pranjal

+0

.get()只會阻止當前的greenlet;其他作業在get()期間運行;還有'值'屬性是None,一旦完成,它將被設置爲'print_head'的返回值。在工作完成之前,「價值」爲「無」。 –