【问题标题】:confusing about autoload_paths vs eager_load_paths in rails 4在 rails 4 中混淆 autoload_paths 与 eager_load_paths
【发布时间】:2013-11-15 09:34:24
【问题描述】:

我读过一篇关于 rails load_paths 的帖子,这里是 link

但是,我仍然对autoload_pathseager_load_paths 之间的区别感到困惑:

我在一个新创建的 Rails 4 项目中对它们进行了测试。似乎它们的运行方式相同,即在开发模式下自动重新加载但在生产模式下。

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    链接文章的作者在这里。这是消除@fkreusch 回答的困惑的尝试。

    在 Ruby 中,您必须要求每个 .rb 文件才能运行其代码。但是,请注意,在 Rails 中,您从未特别需要 app/ 目录中的任何模型、控制器或其他文件。这是为什么?那是因为在 Rails 中app/*autoload_paths 中。这意味着当你在开发中运行你的 Rails 应用程序时(例如通过rails console)——Ruby 还不需要任何模型和控制器。 Rails 使用 ruby​​ 的特殊神奇功能来实际等到代码提到一个常量,比如Book,然后它才会运行require 'book',它在autoload_paths 之一中找到它。这使您在开发中可以更快地启动控制台和服务器,因为在您启动它时不需要任何东西,只有在代码真正需要它时才需要它。

    现在,这种行为有利于本地开发,但生产环境呢?想象一下,在生产环境中,您的服务器执行相同类型的神奇常量加载(自动加载)。这并不是真正的世界末日,您在生产中启动服务器,人们开始浏览您的页面的速度会稍微慢一些,因为有些文件需要自动加载。是的,在服务器“热身”时,这几个初始请求的速度较慢,但​​还不错。除了,这不是故事的结局。

    如果您在 ruby​​ 1.9.x 上运行(如果我没记错的话),那么像这样的自动要求文件不是线程安全的。所以如果你使用像 puma 这样的服务器,你会遇到问题。即使您没有使用多线程服务器,您最好还是让整个应用程序在启动时“主动”被要求。这意味着在生产中,您希望在启动应用程序时完全需要每个模型、每个控制器等,并且您不介意更长的启动时间。这称为急切加载。所有 ruby​​ 文件都被急切地加载,明白吗?但是,如果您的 rails 应用程序没有单个 require 语句,您怎么能做到这一点?这就是eager_load_paths 的用武之地。无论您放入其中,这些路径下的所有目录中的所有文件都将在生产启动时需要。希望这能解决问题。

    请务必注意,eager_load_paths 在开发环境中不活跃,因此您在其中放入的任何内容都不会在开发中立即被急需,只有在生产中。

    还需要注意的是,仅将某些内容放入 autoload_paths 不会使其在生产中快速加载。很遗憾。您还必须将其显式放入eager_load_paths

    另一个有趣的怪癖是,在每个 Rails 应用程序中,app/ 下的所有目录都自动位于autoload_pathseager_load_paths 中,这意味着在那里添加目录不需要进一步的操作。

    【讨论】:

    • 非常详细! ;) 值得一提的是,如果您添加到eager_load_paths 的路径,那么在开发环境中它的行为就像autoload_path(按需加载)。所以根本没有必要添加到autoload_paths 的路径。 (导轨 4.1.0)
    • 感谢您的详细解释。对于这一部分,“autoload_paths 在 Rails 3 和 4 之间的生产中表现不同”,我试过了,但没有用。而且我还没有找到任何文档,你能告诉我在哪里可以找到或如何正确测试吗?谢谢。 (我在 application.rb 中添加了config.eager_load_paths += %W(#{config.root}/lib/tools),并在 tools 目录下触摸了 foo.rb,在 puts 'loading...'; class Foo; end >foo.rb,和rails crails c p检查)
    • 感谢您的解释,但经过一番调查,似乎autoload_paths 在生产中没有急切加载。 (Rails 4.1.7)但恰恰相反,eager_load_paths 中的路径被添加到加载路径并在开发中自动加载。
    • @hakunin - @BigBourin 正确的是,autoload_paths 并不急于在生产中加载。见here
    • 肯定存在问题,我相信是这个问题:github.com/rails/rails/issues/6850 让我相信 Rails 4 他们解决了这个问题。 fxn 评论说“自动加载不是线程安全的,因此用户想要自动加载的任何代码都应该被预先加载,因为他没有对此提出任何要求。”我有点把它当作他们的方向。很惊讶他们没有这样做。 /cc @BigBourin
    【解决方案2】:

    基本上,autoload_paths 是 Rails 用来尝试自动加载类的路径。例如。当您调用Book 时,如果该类尚未加载,它将通过autoload_paths 并在这些路径中查找它。

    在生产中,最好预先加载这些内容以避免自动加载并发问题。为此,它提供了eager_load_paths。当您的应用程序启动时,该列表中的路径将是必需的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-22
      • 2014-06-12
      • 2012-03-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多