Rails 5.1在Puma开发中的ActiveJob未执行特定的排队作业

7
我正在运行Rails 5.1.4服务器(Puma v.3.10.0单模式),但是有一个特定的ActionJob出现了问题,它被正确地排队,但往往从未执行。
我有一些工作。除了1个特定的工作外,所有工作都会按预期异步执行,而且在排队后不久就会执行。
在服务器重新启动后第一次进行新的排队后,我的特定工作会被正确执行。但在第一次成功运行后,它将不会在随后的排队中执行。
我通常使用perform_later排队所有工作。
我也尝试使用rails console排队特定的工作。每当我在控制台中排队时,它会立即执行。甚至在同一会话中也是如此。还尝试使用应用程序中排队时使用的相同参数,在服务器上只排队,从未执行。
我已经检查了日志文件-没有任何错误、致命错误或警告。它只是简单地声明[ActiveJob] Enqueued FooBaaJob,但从未执行该工作。
如果作业实际上失败了,它至少应该在日志中写出[ActiveJob] [FooBaaJob] [id] Performing FooBaaJob,但它没有。根据https://github.com/rails/rails/blob/master/activejob/lib/active_job/logging.rb#L78,如果作业失败,它应该捕获并记录异常。其次,在控制台中它从未运行失败,因此这不应该是问题所在。
有任何想法在哪里查找?

1
你在开发环境中将作业队列设置为什么了? - Daniel Westendorf
async(默认-未显式设置)和所有在default队列中的作业。每当我尝试运行作业队列inline时,它总是成功执行作业。 - mtrolle
你只允许 Puma 使用一个线程的配置,而你正在将这个配置传递给 Puma?这可能是你的问题,因为 async 会生成一个新的线程。 - Daniel Westendorf
我不确定为什么它是单线程的,因为我只是使用rails server命令,没有额外的Puma配置。然而,除了这个特定的作业失败之外,我的所有其他作业都按预期运行。 - mtrolle
1个回答

9

好的,我终于找到了一种调试此问题的方法。

通过在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进行作业初始化,并猜测作业执行以一种即时的方式进行,导致在ActiveJob尝试加载记录时记录没有完全提交到sqlite数据库。我也在MySQL上测试了这个问题,结果相同。

Rails 5.0引入了after_[create|update|destroy]_commit,因此将我的after_create更改为after_create_commit解决了我的问题,现在每次我尝试时作业都会按预期运行。

对于早期版本的Rails,您可以使用on: :create参数或类似参数移动到after_commit


谢谢,我遇到了完全相同的问题:使用after_create回调启动任务。 然而,使用Concurrent.use_stdlib_logger(Logger::DEBUG)进行调试的解决方案似乎已经过时:至少我的IDE会提示Concurrent.use_stdlib_logger调用已被弃用。 - Alexey Grinko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接