我正在Gevent池中执行几十个HTTP请求。
目标是在请求失败时重试一次,但只重试一次。否则,它将引发异常。
如何使用支持重新运行一次HTTP请求的at池编写gevent代码(如果它们失败)?
这种方法能起作用吗?
import requests
import gevent
from gevent.pool import Pool
pool = Pool(10)
def do_request(id):
r = requests.get('http://example.com/%u' % id)
if not r.status_code == 200:
raise RuntimeError(id)
def spawn_greenlet(id, is_retry=False):
if not is_retry:
g = gevent.spawn(id)
g.link_exception(retry_once)
else:
g = pool.spawn(id)
g.link_exception(raise_exception)
return g
def retry_once(greenlet):
return spawn_greenlet(greenlet.exception.args[0])
def raise_exception(greenlet):
if greenlet.exception:
raise greenlet.exception
raise RuntimeError('Unknown error in greenlet processing.')
greenlets = pool.map(spawn_greenlet, [1, 2, 3, 4, 5])
gevent.joinall(greenlets)joinall(greenlets)事件处理程序被调用之前,在do_request内部发生异常之后,retry_once方法是否有可能返回?is_retry kwarg at spawn_greenletgevent.joinall(greenlets)只加入了地图返回的绿地。当出现异常时,是否将原来的绿包替换为retry_once返回的新绿?如果没有,是否继续处理,即使额外的小片仍在运行?在这种情况下,我怎么能等着所有的小包完成呢?Gevent文档非常稀少,而且web中似乎没有其他资源来记录这一点,尽管这是一个相当常见的用例。因此,我不认为这是一个过于本地化的问题。
发布于 2012-12-22 11:25:05
不要使用派生/链接/链接_异常来重新尝试。只需使用普通Python:
def do_something_with_retry(*args):
try:
return do_something(*args)
except Exception:
return do_something(*args)另外,gevent.pool.Pool.map会在给定的池中自动生成绿,您不必这样做。
pool = Pool(10)
pool.map(do_something_with_retry, [1, 2, 3])现在,您只需要实现do_something(),它可以是普通的Python/requests代码:
def do_something(*args):
return requests.get('http://gevent.org')玩得开心!
https://stackoverflow.com/questions/13992785
复制相似问题