【问题标题】:How to handle Celery WorkerLostError due to c++ assertion in python imported module?由于 python 导入模块中的 c++ 断言,如何处理 Celery WorkerLostError?
【发布时间】:2019-06-04 10:20:25
【问题描述】:

我有一个使用 pybind11 的带有 c++ 代码的 python 模块,该模块已导入到我的 django + celery 3.1.25 应用程序中。 C++ 代码包含可能在 celery worker 内部触发的断言,然后导致WorkerLostError

我已经尝试将调用 python c++ 模块放在 try: except: 范围内,但这不起作用并且 celery worker 仍然崩溃。

我还尝试在我的 apply_async 调用中使用 link_error= 参数绑定错误回调函数到我的 celery 任务,但是该方法永远不会被调用。

理想情况下,我想以某种方式捕获错误,以便向用户显示错误消息。任何建议表示赞赏!

【问题讨论】:

  • 澄清一下:C++ 模块是你自己的吗?你能修改它的源代码吗?你能从源代码编译它吗?
  • 是的,我可以修改 c++ 源代码,但我将断言放在那里以捕获意外错误。
  • 断言的使用应该仅限于调试。对于您的生产版本,我将在禁用断言的情况下进行编译。您可能想抛出exception 而不是使用断言,但通常您应该保存断言以检查程序的内部逻辑并使用异常来表示违反合同。
  • 是的,有道理,但是这些断言确实是为了程序的内部逻辑,比如写出数组的边界等等。
  • 它们仍应启用。无论如何,保留用于单元测试和开发构建的断言。但在生产中,它们应该被禁用。

标签: python c++ django celery pybind11


【解决方案1】:

我通常使用subprocess 模块来处理Celery 任务中C++ 二进制文件的执行,特别是subprocess.run。您将获得结果代码(rc)和执行命令产生的标准输出/错误,而不会导致工作进程崩溃(WorkerLost)。最多,通过调用 subprocess.run,您将不得不处理异常,这些异常在非零 rc 上引发,具体取决于关键字参数 check 的值:

如果检查为真,并且进程以非零退出代码退出,则 将引发 CalledProcessError 异常。那的属性 异常保存参数、退出代码以及 stdout 和 stderr if 他们被俘虏了。

但是,我通常更喜欢禁用它并自己检查返回码。

我已广泛使用这种方法来处理预期和意外的返回码,以及由内存泄漏、段错误等产生的操作系统信号 (rc

为了处理和格式化操作系统信号,我使用了signal 模块。

【讨论】:

    猜你喜欢
    • 2015-01-09
    • 2017-03-04
    • 1970-01-01
    • 2019-01-11
    • 2018-03-31
    • 1970-01-01
    • 1970-01-01
    • 2014-07-12
    • 2017-07-12
    相关资源
    最近更新 更多