What data (if any) persists across web-requests in Ruby on Rails?
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 d开发者_Python百科on't know about class variables, instance variables on a class, Eigenclasses, ...
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.
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?
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.
精彩评论