views:

193

answers:

2

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, ...

+1  A: 

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.

tadman
Thanks for the info! I actually want to avoid having my singleton shared across requests. This concern prompted the above question. I think I'll end up using a helper method that instantiates or returns a single instance stored in a controller instance variable. (i.e. `def name_of_view_helper_class; @singleton ||= ViewHelperClass.new; end`) Does this make sense?
Daniel Beardsley
Creating controller instance variables, or even variables within helpers that are re-used throughout the execution of the request, is a fairly standard thing to be doing. The instance of the controller and all the associated variables are destroyed at the end of the request, so you always start with a clean slate each time.
tadman
A: 

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.

Warren
You can inadvertently create persistent state information if you make the mistake of using class variables instead of class instance variables, though, stateless or not. The server has a lot of state information that needs to be compartmentalized in order to not inadvertently carry state from one request to the next, or one session to another.
tadman