# How make persistent in-memory objects?

**URL:** <https://www.ruby-forum.com/t/how-make-persistent-in-memory-objects/118338>\
**Category:** Rails\
**Created:** [October 25, 2007, 8:37pm UTC](https://www.ruby-forum.com/t/how-make-persistent-in-memory-objects/118338 "2007-10-25T20:37:07Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![S-gw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ed655f/32.png) [@S-gw](https://www.ruby-forum.com/u/S-gw)\
**Post date:** [October 25, 2007, 8:37pm UTC](https://www.ruby-forum.com/t/how-make-persistent-in-memory-objects/118338/1 "2007-10-25T20:37:07Z")

</div>

I have data that gets loaded from text files, then parsed into specific  
data structures. I need this data to be persistent within the Rails  
universe available to every request that comes into Rails.

I’m used to a web dev language Lasso where there is a true persisent  
in-memory environment surrounding all requests. Using globals (with some  
read/write thread locking) is a great way to create an in-memory cache  
for many-reads/occasional-writes.

I can’t seem to recreate this in Rails. I attempted to use global var  
like I would in Lasso, but so far that hasn’t proven effective. The var  
appears to get recreated (some confusion about the meaning of “global”  
there, but that may be another topic).

I have caught wind of memcached, but that sounds like overkill for my  
needs (this Rails app will only ever need to run on a single machine).  
Actually, I’ll have several machines, but each needs it’s own cache for  
this data–unique per machine which again is why the global thing was  
perfect in Lasso.

Then there’s the issue of making this data available to multiple  
instances of mogrel/Rails. Lasso is multi-threaded, so there was no need  
to deal with starting an arbitrary number of handlers like is needed  
with Rails.

Anyway, is there a way to create such a critter in Rails, or is  
memcached the only option?

– gw

---

<div class="post-metadata">

**Author:** ![S-gw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ed655f/32.png) [@S-gw](https://www.ruby-forum.com/u/S-gw)\
**Post date:** [October 25, 2007, 9:15pm UTC](https://www.ruby-forum.com/t/how-make-persistent-in-memory-objects/118338/2 "2007-10-25T21:15:23Z")

</div>

> I have data that gets loaded from text files, then parsed into specific  
> data structures. I need this data to be persistent within the Rails  
> universe available to every request that comes into Rails.

In environment.rb you could do:

MY\_SPECIAL\_VAR = “foo”  
MY\_SPECIAL\_VAR.freeze

After that you can access MY\_SPECIAL\_VAR everywhere. And it doesn’t  
need  
to be a string. It could be an array, hash, etc…

You can also make it a little nicer (in terms of how you load it) but  
the  
above will work.

---

<div class="post-metadata">

**Author:** ![S-gw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ed655f/32.png) [@S-gw](https://www.ruby-forum.com/u/S-gw)\
**Post date:** [October 25, 2007, 9:25pm UTC](https://www.ruby-forum.com/t/how-make-persistent-in-memory-objects/118338/3 "2007-10-25T21:25:16Z")

</div>

Philip H. wrote:

> > I have data that gets loaded from text files, then parsed into specific  
> > data structures. I need this data to be persistent within the Rails  
> > universe available to every request that comes into Rails.
> 
> In environment.rb you could do:
> 
> MY\_SPECIAL\_VAR = “foo”  
> MY\_SPECIAL\_VAR.freeze
> 
> After that you can access MY\_SPECIAL\_VAR everywhere. And it doesn’t  
> need  
> to be a string. It could be an array, hash, etc…
> 
> You can also make it a little nicer (in terms of how you load it) but  
> the  
> above will work.

If I’m reading that correctly, it can’t be a constant, and can’t be  
frozen. The cache builds up over time via lazy loads (the “occassional  
write” part).

I tried using a global there, and had other complaints from Rails. I’ll  
fiddle some more there then if that’s supposed to be the place to add it  
(figured it was, but didn’t work first time, might have been a separate  
bug).

– gw

---

<div class="post-metadata">

**Author:** ![S-gw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ed655f/32.png) [@S-gw](https://www.ruby-forum.com/u/S-gw)\
**Post date:** [October 25, 2007, 9:35pm UTC](https://www.ruby-forum.com/t/how-make-persistent-in-memory-objects/118338/4 "2007-10-25T21:35:52Z")

</div>

> Anyway, is there a way to create such a critter in Rails, or is  
> memcached the only option?
> 
> – gw

Creating a Singleton object won’t get what you need? I’ve used them in  
the  
past with Java for this sort of requirement.

–  
Andrew S.

---

<div class="post-metadata">

**Author:** ![S-gw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ed655f/32.png) [@S-gw](https://www.ruby-forum.com/u/S-gw)\
**Post date:** [October 25, 2007, 11:34pm UTC](https://www.ruby-forum.com/t/how-make-persistent-in-memory-objects/118338/5 "2007-10-25T23:34:36Z")

</div>

On Oct 25, 2007, at 2:31 PM, Philip H. wrote:

> After that you can access MY\_SPECIAL\_VAR everywhere. And it  
> doesn’t need  
> to be a string. It could be an array, hash, etc…

Just to play around, I added exactly that to environment.rb, and then  
tried to output it to a template using \<%= MY\_SPECIAL\_VAR %\> and I  
get an unitialize constant error.

Doesn’t matter if I add the declarations at the end of the file or  
inside Rails::Initializer. I’ve even stopped and restarted Rails uses  
mongrel\_rails stop|start.

Most puzzering :-\

– gw

---

<div class="post-metadata">

**Author:** ![S-gw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ed655f/32.png) [@S-gw](https://www.ruby-forum.com/u/S-gw)\
**Post date:** [October 25, 2007, 10:13pm UTC](https://www.ruby-forum.com/t/how-make-persistent-in-memory-objects/118338/6 "2007-10-25T22:13:20Z")

</div>

I don’t know if this is useful to you, but I did this:

# Provide a container for global option storage

# Both getter/setter and [] access methods are

# provided.

class Options  
@@option\_hash = {}

def self.set(option\_name, value)  
option\_name = option\_name.to\_s  
@@option\_hash[option\_name] = value  
end

def self.get(option\_name)  
option\_name = option\_name.to\_s  
@@option\_hash[option\_name]  
end

def self.[]=(option\_name, value)  
option\_name = option\_name.to\_s  
self.set(option\_name, value)  
end

def self.  
option\_name = option\_name.to\_s  
self.get(option\_name)  
end

def self.has\_key?(key)  
key = key.to\_s  
@@option\_hash.has\_key?(key)  
end

def self.key?(key)  
self.has\_key?(key)  
end  
end

Stuck it in ./lib/options.rb

Note that this does not scale across Mongrels or \*CGI processes.

---

<div class="post-metadata">

**Author:** ![S-gw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ed655f/32.png) [@S-gw](https://www.ruby-forum.com/u/S-gw)\
**Post date:** [October 25, 2007, 11:36pm UTC](https://www.ruby-forum.com/t/how-make-persistent-in-memory-objects/118338/7 "2007-10-25T23:36:57Z")

</div>

On 10/25/07, Greg W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Just to play around, I added exactly that to environment.rb, and then  
> tried to output it to a template using \<%= MY\_SPECIAL\_VAR %\> and I  
> get an unitialize constant error.

Did you restart your server? Changes to environment.rb won’t show up  
otherwise.

–  
Greg D.  
[http://destiney.com/](http://destiney.com/)

---

<div class="post-metadata">

**Author:** ![S-gw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ed655f/32.png) [@S-gw](https://www.ruby-forum.com/u/S-gw)\
**Post date:** [October 25, 2007, 11:54pm UTC](https://www.ruby-forum.com/t/how-make-persistent-in-memory-objects/118338/8 "2007-10-25T23:54:33Z")

</div>

On Oct 25, 2007, at 2:36 PM, Greg D. wrote:

> On 10/25/07, Greg W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > Just to play around, I added exactly that to environment.rb, and then  
> > tried to output it to a template using \<%= MY\_SPECIAL\_VAR %\> and I  
> > get an unitialize constant error.
> 
> Did you restart your server? Changes to environment.rb won’t show  
> up otherwise.

I believe I did. That is, I beat out some commands, but whether they  
worked…

I’m starting using mongrel\_rails start -d -p 3001

I’m stopping with mongrel\_rails stop -P /path/to/mongrel.log

I get a “terminated” back, then I start again.

– gw

---

<div class="post-metadata">

**Author:** ![S-gw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ed655f/32.png) [@S-gw](https://www.ruby-forum.com/u/S-gw)\
**Post date:** [October 26, 2007, 12:05am UTC](https://www.ruby-forum.com/t/how-make-persistent-in-memory-objects/118338/9 "2007-10-26T00:05:39Z")

</div>

On 10/25/07, Greg W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I believe I did. That is, I beat out some commands, but whether they  
> worked…
> 
> I’m starting using mongrel\_rails start -d -p 3001
> 
> I’m stopping with mongrel\_rails stop -P /path/to/mongrel.log
> 
> I get a “terminated” back, then I start again.

On a development setup you would usually just run script/server which  
will run mongrel for you. Then it’s just Ctrl + C, up, and enter to  
restart it.

–  
Greg D.  
[http://destiney.com/](http://destiney.com/)

---

<div class="post-metadata">

**Author:** ![S-gw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ed655f/32.png) [@S-gw](https://www.ruby-forum.com/u/S-gw)\
**Post date:** [October 26, 2007, 12:16am UTC](https://www.ruby-forum.com/t/how-make-persistent-in-memory-objects/118338/10 "2007-10-26T00:16:10Z")

</div>

On Oct 25, 2007, at 3:04 PM, Greg D. wrote:

> On a development setup you would usually just run script/server which  
> will run mongrel for you. Then it’s just Ctrl + C, up, and enter to  
> restart it.

I started with that using Webrick, then added something (I forget  
already what I did, edited a file?) so that it would use mongrel  
instead, but that leaves a Terminal window open with all the noise  
flying by that I’m not interested in yet, so been using the above -d  
option.

However, just for giggles, I stopped, then fired up with just script/  
server. Still get complaint of an undefined constant.

Hrmm.

– gw

---

<div class="post-metadata">

**Author:** ![S-gw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ed655f/32.png) [@S-gw](https://www.ruby-forum.com/u/S-gw)\
**Post date:** [October 26, 2007, 12:31am UTC](https://www.ruby-forum.com/t/how-make-persistent-in-memory-objects/118338/11 "2007-10-26T00:31:57Z")

</div>

> > I have data that gets loaded from text files, then parsed into  
> > specific data structures. I need this data to be persistent within  
> > the Rails  
> > universe available to every request that comes into Rails.

On Oct 25, 2007, at 1:12 PM, s.ross wrote:

> I don’t know if this is useful to you, but I did this:

yeah, I may end up with a proper class for the cache, meanwhile my  
main propblem is getting a variable to survive across multiple Rails  
page loads.

Here’s a stripped down version of what I am doing.

#! /usr/local/bin/ruby

class ConfigData

if defined? $configCache == nil  
self.resetCache  
end

def resetCache  
$configCache = Hash.new  
end

def getData  
if $configData.has\_key?(‘testing’)  
puts ‘found in cache’  
else  
$configData.store(‘testing’,‘test data’)  
puts ‘added to cache’  
p $configData  
end  
end  
end

x = ConfigData.new

3.times do |i|  
x.getData  
end

y = ConfigData.new

3.times do |i|  
y.getData  
end

This works as expected with all accesses after the first one pulling  
from the global. Like I say, it’s a cheap way to have a cache created  
on the fly dedicated to the needs of just this class.

If I put this into a rails project as /lib/config\_data.rb (separated  
for ERB template, etc), I also get what I expect on the first pass.  
First load creates the global and populates the cache. After that  
the .getData pulls from the global.

The problem I am having is that when I reload the test page, I would  
expect to see _all_ .getData calls pull from the cache – meaning the  
global is stil intact and still has data. Instead I see a repeat of  
the first pass. The global has to be created and populated, then  
subsequent .getData calls pull from the global.

This is where I’m puzzled, and where a global is either not a global,  
or the way Rails runs inside Ruby is working differently than I  
expected.

If I move the global declaration to environment.rb, I gets complaints  
from Rails that it was never declared – so, whatever is going on  
there I think is the real problem.

Appreciate everyone chipping in so far. Thx.

– gw

---

<div class="post-metadata">

**Author:** ![S-gw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ed655f/32.png) [@S-gw](https://www.ruby-forum.com/u/S-gw)\
**Post date:** [October 26, 2007, 10:27am UTC](https://www.ruby-forum.com/t/how-make-persistent-in-memory-objects/118338/12 "2007-10-26T10:27:19Z")

</div>

Well, after all was said and done I ended up rebooting the whole  
machine, and that seems to have cured whatever the heck was going  
wrong. Even stopping and starting the server had no effect. Something  
was hosed.

My global cache thing works as expected, and that weird inability to  
add vars to environment.rb is fixed.

Thanks to everyone for your suggestions.

– gw

---

<div class="post-metadata">

**Author:** ![S-gw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ed655f/32.png) [@S-gw](https://www.ruby-forum.com/u/S-gw)\
**Post date:** [October 26, 2007, 6:13am UTC](https://www.ruby-forum.com/t/how-make-persistent-in-memory-objects/118338/13 "2007-10-26T06:13:43Z")

</div>

On Oct 25, 2007, at 2:31 PM, Philip H. wrote:

> After that you can access MY\_SPECIAL\_VAR everywhere. And it  
> doesn’t need  
> to be a string. It could be an array, hash, etc…
> 
> You can also make it a little nicer (in terms of how you load it)  
> but the  
> above will work.

Following up on this one, I’m still having no luck even toying with  
this.

I’ve gone so far as to do this:

# Specifies gem version of Rails to use when vendor/rails is not present

RAILS\_GEM\_VERSION = ‘1.2.5’ unless defined? RAILS\_GEM\_VERSION

MY\_TEST\_VAR = “foo”

And in a given template I can output RAILS\_GEM\_VERSION just fine, but  
MY\_TEST\_VAR cause a crash with an undefined contstant error. What is  
up with that one ??

It doesn’t matter what var I declare at any point inside  
environment.rb or development.rb, every one crashes saying it has not  
been declared. Freaking me out.

– gw

---

<div class="post-metadata">

**Author:** ![S-gw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ed655f/32.png) [@S-gw](https://www.ruby-forum.com/u/S-gw)\
**Post date:** [October 27, 2007, 5:58am UTC](https://www.ruby-forum.com/t/how-make-persistent-in-memory-objects/118338/14 "2007-10-27T05:58:40Z")

</div>

removed\_email\_address@domain.invalid wrote:

> You could use the built-in Ruby SDBM persistent hashing solution.  
> It’s extremely fast and will run under Rails or any Ruby application  
> on any web server. The best part is it’s included in Ruby - no  
> plugins or gems!
> 
> I covered it on one of my earlier Rubyology screencasts (http://  
> [rubyology.com/mp3s/rubyology25.mov](http://rubyology.com/mp3s/rubyology25.mov)).

OK, cool. Thx.

\<% plug(:shameless =\> true) %\>

Have a look at [http://www.screencastapp.com/](http://www.screencastapp.com/) for your screencasting. (My  
son wrote it, and just released it. A lot of satisfied people so far 🙂

\<% end %\>

– gw

---

<div class="post-metadata">

**Author:** ![S-gw](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ed655f/32.png) [@S-gw](https://www.ruby-forum.com/u/S-gw)\
**Post date:** [October 27, 2007, 4:35am UTC](https://www.ruby-forum.com/t/how-make-persistent-in-memory-objects/118338/15 "2007-10-27T04:35:01Z")

</div>

You could use the built-in Ruby SDBM persistent hashing solution.  
It’s extremely fast and will run under Rails or any Ruby application  
on any web server. The best part is it’s included in Ruby - no  
plugins or gems!

I covered it on one of my earlier Rubyology screencasts (http://  
[rubyology.com/mp3s/rubyology25.mov](http://rubyology.com/mp3s/rubyology25.mov)).

Cheers,  
Chris Matthieu  
[http://www.rubyology.com](http://www.rubyology.com)
