Rails 5.1 Puma 开发中的 ActiveJob 不执行特定的排队作业
Rails 5.1 ActiveJob on Puma development not performing specific enqueued job
我正在 运行ning Rails 5.1.4 服务器(单模式下的 Puma v. 3.10.0),但是特定的 ActionJob 有一个问题,它被正确地排队但通常永远不会执行。
我有几份工作。除了 1 个特定作业外,所有作业总是在入队后不久按预期异步执行。
服务器重新启动后第一次我的特定作业在新队列后正确执行。但是在第一次成功运行之后,它不会在后续的排队中执行。
我通常使用 perform_later
对所有作业进行排队。
我也测试过使用 rails console
对特定作业进行排队。每当我在控制台中对其进行排队时,它都会立即执行。即使在同一个会话中。还尝试使用与在 rails server
中排队时应用程序中使用的参数相同的参数,但在服务器中它仅排队。从未表演过。
我检查了日志文件 - 没有任何内容,没有错误,没有致命错误,也没有警告。它只是声明 [ActiveJob] Enqueued FooBaaJob
,但从不执行作业。
如果作业真的失败了,它至少应该在日志中写出 [ActiveJob] [FooBaaJob] [id] Performing FooBaaJob
,但事实并非如此。
根据 https://github.com/rails/rails/blob/master/activejob/lib/active_job/logging.rb#L78 它实际上应该捕获并记录失败的异常。其次,它在控制台中永远不会失败 运行,所以不应该是这样。
关于去哪里看有什么想法吗?
好的,所以我终于找到了调试这个问题的方法。
通过在 config/initializers
中使用以下行创建初始化文件:
Concurrent.use_stdlib_logger(Logger::DEBUG)
我现在将错误数据输出到我的控制台。
[ActiveJob] Enqueued FooBaaJob (Job ID: ...) to Async(default) with arguments: #<GlobalID:0...0 @uri=#<URI::GID gid://test-app/FooBaa/8>>
[2017-10-29 16:10:56.676] DEBUG -- : Error while trying to deserialize arguments: Couldn't find FooBaa with 'id'=8 (ActiveJob::DeserializationError)
第二行是添加Concurrent.use_stdlib_logger(Logger::DEBUG)
启动器文件的结果
在我的例子中,我在我的模型中的 after_create
中启动作业,我猜测作业执行以某种方式瞬间发生,导致记录没有完全提交给 sqlite db 但当 ActiveJob 试图加载它时。它也在 MySQL 上进行了测试,结果相同。
Rails 5.0 引入了 after_[create|update|destroy]_commit
,因此将我的 after_create
更改为 after_create_commit
解决了我的问题,现在我每次都按预期工作 运行正在尝试。
对于 Rails 的早期版本,您可以使用 on: :create
参数或类似参数移动到 after_commit
。
我正在 运行ning Rails 5.1.4 服务器(单模式下的 Puma v. 3.10.0),但是特定的 ActionJob 有一个问题,它被正确地排队但通常永远不会执行。
我有几份工作。除了 1 个特定作业外,所有作业总是在入队后不久按预期异步执行。
服务器重新启动后第一次我的特定作业在新队列后正确执行。但是在第一次成功运行之后,它不会在后续的排队中执行。
我通常使用 perform_later
对所有作业进行排队。
我也测试过使用 rails console
对特定作业进行排队。每当我在控制台中对其进行排队时,它都会立即执行。即使在同一个会话中。还尝试使用与在 rails server
中排队时应用程序中使用的参数相同的参数,但在服务器中它仅排队。从未表演过。
我检查了日志文件 - 没有任何内容,没有错误,没有致命错误,也没有警告。它只是声明 [ActiveJob] Enqueued FooBaaJob
,但从不执行作业。
如果作业真的失败了,它至少应该在日志中写出 [ActiveJob] [FooBaaJob] [id] Performing FooBaaJob
,但事实并非如此。
根据 https://github.com/rails/rails/blob/master/activejob/lib/active_job/logging.rb#L78 它实际上应该捕获并记录失败的异常。其次,它在控制台中永远不会失败 运行,所以不应该是这样。
关于去哪里看有什么想法吗?
好的,所以我终于找到了调试这个问题的方法。
通过在 config/initializers
中使用以下行创建初始化文件:
Concurrent.use_stdlib_logger(Logger::DEBUG)
我现在将错误数据输出到我的控制台。
[ActiveJob] Enqueued FooBaaJob (Job ID: ...) to Async(default) with arguments: #<GlobalID:0...0 @uri=#<URI::GID gid://test-app/FooBaa/8>>
[2017-10-29 16:10:56.676] DEBUG -- : Error while trying to deserialize arguments: Couldn't find FooBaa with 'id'=8 (ActiveJob::DeserializationError)
第二行是添加Concurrent.use_stdlib_logger(Logger::DEBUG)
启动器文件的结果
在我的例子中,我在我的模型中的 after_create
中启动作业,我猜测作业执行以某种方式瞬间发生,导致记录没有完全提交给 sqlite db 但当 ActiveJob 试图加载它时。它也在 MySQL 上进行了测试,结果相同。
Rails 5.0 引入了 after_[create|update|destroy]_commit
,因此将我的 after_create
更改为 after_create_commit
解决了我的问题,现在我每次都按预期工作 运行正在尝试。
对于 Rails 的早期版本,您可以使用 on: :create
参数或类似参数移动到 after_commit
。