这是 Rails v5.2.3。我有一个特定的 Sidekiq 作业,其中许多作业实例似乎挂起 20 多分钟。在队列所在的同一台机器上,当发生这种情况时,我可以在 Rails 控制台中运行相同的代码,并在 5 秒内完成。
我从 Sidekiq 屏幕上确定了有问题的 PID,并运行:
kill -TTIN <pid>
以下行在文件中出现了两次,我猜这意味着来自同一进程的两个线程正在尝试加载同一文件:
Oct 13 17:04:08 myapp-production sidekiq[1217886]: /myapp/shared/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/core_ext/module/introspection.rb:35:in `parent'
Oct 13 17:04:08 myapp-production sidekiq[1217886]: /myapp/shared/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/dependencies.rb:516:in `load_missing_constant'
Oct 13 17:04:08 myapp-production sidekiq[1217886]: /myapp/shared/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/dependencies.rb:195:in `const_missing'
Oct 13 17:04:08 myapp-production sidekiq[1217886]: /myapp/releases/20221013144458/lib/mixins/query_builder.rb:294:in `generate_sql'
我确实有一些require
在我的代码中不同的地方,我刚刚确定这显然是不好的。然而,我不是require
编译上面列出的文件:lib/mixins/query_builder.rb
。它是一个模块 extend
来自 lib/classes
中几个不同类(class)的编辑.
在我的config/application.rb
文件,我有:
config.enable_dependency_loading = true
config.eager_load_paths += %W[
#{config.root}/app/actions
#{config.root}/app/organizers
#{config.root}/lib/my_stuff
#{config.root}/lib/mixins
#{config.root}/lib/classes
]
config.autoload_paths += %W[
#{config.root}/app/actions
#{config.root}/app/organizers
#{config.root}/lib
#{config.root}/lib/my_stuff
#{config.root}/lib/mixins
#{config.root}/lib/classes
#{config.root}/lib/*
我承认这很困惑,我不确定这里发生了什么。我有config.eager_load
在生产中设置为 true,在开发中设置为 false。
所以,如果 lib/mixins
出现在 eager_load_paths
中和autoload_paths
,为什么 ActiveSupport 的 const_missing
被触发?我应该采取什么措施来纠正这种情况?
另外,如果我做这个 QueryBuilder
会更好吗?我可以创建一个对象的实例,以避免两个线程使用同一程序。换句话说,就是extend
QueryBuilder
中借用功能的错误方法到多个类(class)?
作为第二个请求,如果有人可以为我指明正确的方向,以正确的方式配置我的 eager_load_paths
和autoload_paths
,这将在升级此应用程序之前提供很大帮助。
提前非常感谢您的帮助。
最佳答案
这是“为什么我看到自动加载”的答案。
在急切加载过程中仍可能发生自动加载。
假设您有
class Foo
include QueryBuilder
end
如果 Rails 急于加载 Foo
并且此时 lib/mixins/query_builder.rb
尚未被访问,则仅评估 foo.rb
触发第 2 行中 QueryBuilder
的自动加载。
该配置有点困惑(正如您所说)。我们可以努力简化您喜欢的内容。
为什么该作业在控制台中花费了 20 分钟和 5 分钟?不知道和这个有没有关系。当 Sidekiq 启动时,应用程序已启动并且文件已预先加载。
关于ruby-on-rails - 为什么 Rails 尝试在生产环境中自动加载此文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74082541/