在创建视图助手类时,我决定使用singleton设计模式。这让我思考:单例实例会跨请求存活吗?这引出了另一个问题,哪些变量(如果有的话)在web请求中存在,这是否会随着部署的不同而变化?(Fastcgi,Mongrel,Passenger,...)
我知道控制器实例变量不是持久化的。我知道常量是持久化的(或者重新加载?)。但是我不知道类变量,类上的实例变量,特征类,...
发布于 2010-05-08 04:50:41
简单的答案是没有。每个请求都被视为一个独立的事件,除了存储在用户会话和任何外部数据库、缓存或文件存储中的信息外,不会传递任何状态信息。最好在设计应用程序时牢记这一点,不要仅仅因为设置了它们就期望它们能够持久存在。
更复杂的情况是,有些事情确实存在。例如,您可以在控制器上创建一个类变量,正如您所期望的那样,它将从一个请求传递到下一个请求。问题是,这只适用于包含在该进程中的控制器的单个实例,而不适用于由其他进程服务的请求。如果您需要缓存,请利用Rails.cache基础设施,并避免在您自己的基础设施中进行黑客攻击。
典型的生产环境是一个复杂的、不断变化的环境,其中流程不断地被创建和销毁,并且没有办法预先确定哪个流程最终将服务于特定的请求。由于许多部署不仅涉及单个机器上的多个进程,而且还涉及多个机器,因此确实没有实际的方法来创建应用程序范围的单例对象。
您可以做的最好的事情是在缓存引擎之上构建一个层,其中您的单例对象仅仅是从缓存获取和写入的函数的包装器。这为您提供了单例对象的外观,同时保持了进程间的一致性。
发布于 2017-12-07 18:35:58
我知道这篇文章很老了,但是对于正在寻找解决方案的人来说,可以使用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
我正在做的是在一个路由上接收一个请求,向Zapier发送一个GET,然后在另一个路由上等待答案。Rails为每个请求打开一个新的Thread,所以我在RAM中以'key: value‘格式写入数据
发布于 2010-05-08 04:50:57
网络是一种无状态的媒介。除非您故意在会话中保存数据,或者在get或post中传递数据,否则每个web请求都会以空白板开始。将页面传送到web浏览器后,使用当前请求创建的任何对象都会被销毁。
https://stackoverflow.com/questions/2791093
复制相似问题