哪些数据(如果有)在 Ruby on Rails 中的 Web 请求中持续存在?

发布于 2024-08-31 16:59:14 字数 237 浏览 4 评论 0原文

我决定在创建视图助手类时使用单例设计模式。这让我思考;单例实例会在请求中生存吗?这引发了另一个问题,哪些变量(如果有)在 Web 请求中仍然存在,并且这些变量会根据部署而变化吗? (Fastcgi、Mongrel、Passenger,...)

我知道控制器实例变量不会被持久化。我知道常量被持久化(或重新加载?)。但我不知道类变量、类上的实例变量、特征类……

I decided to use the singleton design pattern while creating a view helper class. This got me thinking; will the singleton instance survive across requests? This led to another question, Which variables (if any) survive across web requests and does that change depending on deployment? (Fastcgi, Mongrel, Passenger, ...)

I know that Controller instance variables aren't persisted. I know Constants are persisted (or reloaded?). But I don't know about class variables, instance variables on a class, Eigenclasses, ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

就像说晚安 2024-09-07 16:59:14

简单的答案是否定的。每个请求都被视为一个独立的事件,除了用户会话和任何外部数据库、缓存或文件存储中存储的信息之外,不会传递任何状态信息。最好在设计应用程序时考虑到这一点,而不是仅仅因为您设置了它们就期望事情会持续存在。

更复杂的故事是,有些事情确实持续存在。例如,您可以在控制器上创建一个类变量,并且该变量将按照您的预期从一个请求传递到下一个请求。问题是,这仅适用于该进程中包含的该控制器的单个实例,而不适用于其他进程提供的请求。如果您需要缓存,请使用 Rails.cache 基础设施并避免自己进行黑客攻击。

典型的生产环境是一个复杂、不断变化的事物,其中流程不断创建和销毁,并且无法提前确定哪个流程最终将服务于特定请求。由于许多部署不仅涉及单台机器上的多个进程,而且还涉及多台机器,因此实际上没有实际的方法来创建应用程序范围的单例对象。

您能做的最好的事情就是在缓存引擎之上构建一个层,其中您的单例对象只是从缓存中获取和写入的函数的包装器。这为您提供了单例对象的外观,同时保持了进程间的一致性。

The simple answer is none. Each request is treated as an independent event and no state information is carried over apart from what is stored in the user session and any external databases, caches, or file stores. It is best that you design your application with this in mind and not expect things to persist just because you've set them.

The more complicated story is that some things do persist. For example, you can create a class variable on a controller and this will be carried from one request to the next as you might expect. The catch is that this only applies to the singular instance of that controller, as contained within that process, and will not apply to requests served by other processes. If you need caching, make use of the Rails.cache infrastructure and avoid hacking in your own.

A typical production environment is a complicated, ever-changing thing, where processes are created and destroyed constantly and there is no way to determine in advance which process will ultimately end up serving a particular request. As many deployments involve not only multiple processes on a single machine, but multiple machines, there really is no practical way to create application-wide singleton objects.

The best thing you can do is build a layer on top of the caching engine where your singleton object is merely a wrapper to functions that fetch and write from the cache. This gives you the appearance of a singleton object while maintaining inter-process consistency.

温柔一刀 2024-09-07 16:59:14

我知道这篇文章已经过时了,但是对于正在寻找解决方案的人来说,可以使用 Rails.Cache,如下所示:

class TestEventsController < ApplicationController
  require 'httparty'

  @@cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 5.minutes)

  before_action :get_data, only: [:get]
  before_action :get_response, only: [:set]

  def get
    uri = "https://hooks.zapier.com/hooks/catch/zap_id/"
    event_id = event_id_generate()
    @@cache.write(event_id, "")

    result = HTTParty.post(uri.to_str,
    :body => {id: event_id, data: @data}.to_json,
    :headers => {'content-Type' => 'application/json'})
    sleep 2
    render json: { 'value': @@cache.read(event_id) }, status: 200
  end

  def set
    @@cache.write(@id, @value)
    render json: { 'value': @@cache.read(@id) }, status: 200
  end

  def get_data
    @data = params["data"]
  end
  def get_response
    @id = params["id"]
    @value = params["value"]
  end

  def event_id_generate
    token = SecureRandom.urlsafe_base64(10, false)
  end
end

我正在做的是在路由中接收请求,将 GET 发送到 Zapier,然后等待在另一条路线上回答。 Rails 为每个请求打开一个新线程,因此我以“key: value”格式将数据写入 RAM

Rails.cache在不同线程中不缓存?

I know that this post is old, but for who is looking a solution, it's possible to use Rails.Cache, like this:

class TestEventsController < ApplicationController
  require 'httparty'

  @@cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 5.minutes)

  before_action :get_data, only: [:get]
  before_action :get_response, only: [:set]

  def get
    uri = "https://hooks.zapier.com/hooks/catch/zap_id/"
    event_id = event_id_generate()
    @@cache.write(event_id, "")

    result = HTTParty.post(uri.to_str,
    :body => {id: event_id, data: @data}.to_json,
    :headers => {'content-Type' => 'application/json'})
    sleep 2
    render json: { 'value': @@cache.read(event_id) }, status: 200
  end

  def set
    @@cache.write(@id, @value)
    render json: { 'value': @@cache.read(@id) }, status: 200
  end

  def get_data
    @data = params["data"]
  end
  def get_response
    @id = params["id"]
    @value = params["value"]
  end

  def event_id_generate
    token = SecureRandom.urlsafe_base64(10, false)
  end
end

What I'm doing is receive a request in a route, sending a GET to Zapier, and waiting for the answer in another route. Rails opens a new Thread for each request, so I write in the RAM my data in format 'key: value'

Rails.cache in different threads not caching?

花开浅夏 2024-09-07 16:59:14

网络是一种无状态的媒介。除非您故意在会话中保存数据或在 get 或 post 中传递数据,否则每个 Web 请求都会以空白开始。一旦页面传送到 Web 浏览器,使用当前请求创建的任何对象都会被销毁。

The web is a stateless medium. Unless you purposely save data in a session or pass it in a get or post, each web request starts with a blank slate. Any objects created with the current request are destroyed once the page is delivered to the web browser.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文