我正在运行Rails 5.1.4服务器(Puma v.3.1.0.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,你可以使用after_commit
参数或类似的方法移动到on: :create
。