【问题标题】:Why does Rails create a controller for every request?为什么 Rails 为每个请求创建一个控制器?
【发布时间】:2012-12-19 19:50:36
【问题描述】:

从我之前的question 了解到,Rails 会为每个请求创建一个控制器实例。

我的问题是,因为这个主题与我正在从事的项目的设计有关:

Rails 为什么要创建一个新的实例

class SomeController < ApplicationController; end

处理每个传入的请求?为什么不直接创建单例对象并将请求转发给这个对象呢?这似乎更有效,因为我们不会浪费资源来分配和清理请求的对象?

【问题讨论】:

  • 好问题,你应该问 DHH :) 但我认为主要的一点是绝对隔离一个环境到另一个环境。因为否则系统必须为分配逻辑花费更多的处理能力。恕我直言
  • 因为在不存在踩踏其他请求数据的风险时更容易推理代码。
  • 不出意外,但 Grails 似乎也在做同样的事情。

标签: ruby-on-rails controller


【解决方案1】:

实例化一个新控制器实例的开销是微不足道的,这意味着两个完全不相关的请求之间不会意外共享状态。处理器时间的任何“节省”都将被产生破坏性错误的可能性所抵消。

请记住,控制器用于存储特定于请求的状态。重用控制器将要求您在每个操作开始时重置您曾经设置的每个@variable。否则,像@is_admin = true 这样的东西可能会被设置并且永远不会被清除。您实际上引入的不那么人为的错误会更加微妙,并且会占用开发人员的时间。

您会看到没有优化的地方。 某些东西 必须在请求之间保持状态并重置它,否则您会遇到意外共享状态的噩梦。如果您在请求之间持久化控制器实例,您只是将维护/重置状态的工作推到较低级别,答案可能仍然是实例化一些状态管理的新实例每个请求的类。计算机在分配和释放资源方面非常好,所以在您真正知道这是一个瓶颈之前,永远不要担心。在这种情况下,为每个请求实例化一个新的控制器很容易是正确的选择。

对于 Rails,能够使用 @variable = value 从代码清晰度和可用性的角度来看是一个重大胜利,这或多或少需要在请求完成时丢弃控制器的每个实例。

【讨论】:

  • 嗯...这并不是说@foo 总是需要被清除,而是需要编写控制器以使其不具有共享状态,例如Java servlet。您将使用与 Java 中不同的机制(本地、请求等)将值传递给视图层。控制器仅用于存储特定于请求的状态因为它们是按请求实例化的——尽管它不是控制器概念所固有的;其他框架的做法不同。我知道你知道,只是澄清一下。
  • @DaveNewton 是的,我考虑过这个,但问题是关于性能,所以我认为它包含在“某些必须重置请求之间的状态”中。要点是,保留控制器实例并没有提高性能。您只是在移动分配/解除分配。
  • 同意,我更喜欢每个请求的实例:少思考。
猜你喜欢
  • 1970-01-01
  • 2011-07-22
  • 2022-01-24
  • 2023-04-07
  • 2013-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-07
相关资源
最近更新 更多