【发布时间】:2020-04-25 13:50:50
【问题描述】:
我有一组任务,每个任务都向标准 oauth API 端点发出请求,并且依赖于 bearer_token。如果 bearer_token 过期,任务将在响应处理期间引发异常。还有一个refresh_bearer_token 任务,它处理令牌过期后的更新。
这是一个伪代码:
from proj.celery import app
bearer_token = '1234'
class OauthError(Exception):
pass
@app.task
def api_request():
response = request(bearer_token, ...)
if response.bearer_token_expired:
raise OauthError('oauth')
@app.task
def refresh_bearer_token():
...
如何安排refresh_bearer_token 任务在引发OauthError 时执行?
我能找到的唯一解决方案是像这样使用link_error kwarg:
@app.task
def error_callback(uuid):
exception_msg = AsyncResult(uuid).get(propagate=False, disable_sync_subtasks=False)
if exception_msg = 'oauth':
refresh_bearer_token.delay()
else:
raise
api_request.apply_async(link_error=error_callback.s())
但这似乎不是最理想的,原因有几个,最明显的是因为它在另一个同步子任务中产生了一个同步子任务,在文档中 strongly discourged。
在 celery 中是否有更 pythonic 的异常捕获方式?
例如:
def catch(func_that_requires_oauth):
try:
func_that_requires_oauth.delay()
except OauthError:
refresh_bearer_token.delay() | func_that_requires_oauth.delay()
【问题讨论】:
-
你有多少个工人,他们会在到期时开始
refresh_bearer_token任务吗? -
@IainShelvington 为了这个例子,假设我有几个工人。这是我没有考虑的一个好点,因为在我的示例中他们会执行几个
refresh_bearer_token调用,但不应该。 -
这有点超出了这个问题的范围,但我还必须考虑给定队列中有多少个客户端(每个客户端 1 个 Bearer_token)。
-
是否有多个不同的任务都需要这个 oauth 令牌?
-
@IainShelvington 是的。
标签: python django python-3.x celery