[英]Gevent: Retry greenlet once
我在Gevent池中做了几十个HTTP请求。
目标是在失败时重试一次请求,但只返回一次。 否则,它应该抛出异常。
如果它们失败,我将如何在支持重新运行HTTP请求的池中编写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
is_retry spawn_greenlet
? gevent.joinall(greenlets)
只加入map返回的greenlets。 当出现异常时,是否将原始greenlet替换为retry_once
返回的新retry_once
? 如果没有,即使其他greenlet仍在运行,处理是否仍在继续? 在这种情况下,我怎么能等待所有的greenlets完成? Gevent文档非常稀缺,网络中似乎没有其他资源记录这一点,即使这是一个相当常见的用例。 因此,我不认为这是一个太局部化的问题。
不要使用spawn / link / link_exception来重试。 只需使用普通的Python:
def do_something_with_retry(*args):
try:
return do_something(*args)
except Exception:
return do_something(*args)
此外,gevent.pool.Pool.map会自动在给定池中生成greenlet,您不必这样做。
pool = Pool(10)
pool.map(do_something_with_retry, [1, 2, 3])
现在,您只需要实现do_something()
,它可以是普通的Python /请求代码:
def do_something(*args):
return requests.get('http://gevent.org')
玩得开心!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.