在Heroku上处理RQ中的异常处理和重新排队

jdo*_*dot 6 python queue heroku redis

我有一个在Python上运行Heroku的网站,我有一个工作人员作为后台进程来处理我不想阻止网页传递的任务,因此不适合webdynos.为此,我使用rq和redis 设置了一个队列.

在我的过程中,偶尔会出现自定义异常.对于这些的特定子集,我不想让作业直接进入"失败"队列,而是想要将其重新排队几次.我一直在寻找主页上的异常处理程序页面rq,我不清楚一些事情.特别是,它描述了编写异常处理程序的以下方法:

def my_handler(job, exc_type, exc_value, traceback):
    # do custom things here
    # for example, write the exception info to a DB
    ...
Run Code Online (Sandbox Code Playgroud)

现在,我打算按照以下方式做一些事情:

   from rq import requeue_job
   def my_handler(job, exc_type, exc_value, traceback):
        if exec_type == "MyCustomError":
           job.meta['MyErrorCount'] += 1
           job.save()

           if job.meta['MyErrorCount'] >= 10:
               return True
           else:
               requeue_job(job.id)
               return False
Run Code Online (Sandbox Code Playgroud)

问题:

  • 什么类型的对象是exc_type,exc_valuetraceback?(例如,这条线if exec_type == "MyCustomError"是否正确?)
  • 我的错误处理程序是否会有效地检测它是否是特定错误,将这些作业重新排队直到它失败10次,然后让它落到failed?它还会让所有其他错误落到failed

小智 6

这是我的解决方案

queues = []

def retry_handler(job, exc_type, exc_value, traceback):
    # Returning True moves the job to the failed queue (or continue to
    # the next handler)

    job.meta.setdefault('failures', 1)
    job.meta['failures'] += 1
    if job.meta['failures'] > 3 or isinstance(exc_type, (LookupError, CorruptImageError)):
        job.save()
        return True

    job.status = Status.QUEUED
    for queue_ in queues:
        if queue_.name == job.origin:
            queue_.enqueue_job(job, timeout=job.timeout)
            break
    else:
        return True  # Queue has disappeared, fail job

    return False  # Job is handled. Stop the handler chain.

queues.append(Queue(exc_handler=retry_handler))
Run Code Online (Sandbox Code Playgroud)

除非遇到某种已知的异常类型,否则我决定重试所有错误三次.这允许我尊重理解的失败,例如在创建作业之后但在执行作业之前删除用户,或者在图像调整大小作业的情况下,不再找到提供的图像(HTTP 404)以可读格式(基本上每当我知道代码永远不会处理作业).

回答你的问题:exc_type是类,exc_value是异常实例.traceback对日志记录很有用.如果您关心这一点,请查看Sentry.如果SENTRY_DSN在上下文中运行,则工作程序会自动配置Sentry错误处理程序.比使用错误日志污染您自己的数据库更清洁.