# \[ANN\] ActiveRecord + memcache = cached\_model

**URL:** <https://www.ruby-forum.com/t/ann-activerecord-memcache-cached-model/52690>\
**Category:** Rails\
**Created:** [January 18, 2006, 12:45am UTC](https://www.ruby-forum.com/t/ann-activerecord-memcache-cached-model/52690 "2006-01-18T00:45:20Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![miracleofmagick](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/71c47a/32.png) [@miracleofmagick](https://www.ruby-forum.com/u/miracleofmagick)\
**Post date:** [January 18, 2006, 12:45am UTC](https://www.ruby-forum.com/t/ann-activerecord-memcache-cached-model/52690/1 "2006-01-18T00:45:20Z")

</div>

Courtesy of The Robot Co-op.

$ yes | sudo gem install cached\_model

Or, you can download cached\_model and memcache-client (our zippy-fast  
memcache library, required) from:

[http://rubyforge.org/frs/?group\_id=1266](http://rubyforge.org/frs/?group_id=1266)

I don’t have the README posted for making cached\_model work online  
yet, so here it is:

= CachedModel

Rubyforge Project:

[http://rubyforge.org/projects/rctools/](http://rubyforge.org/projects/rctools/)

== About

CachedModel stores Rails ActiveRecord objects in memcache allowing  
for very  
fast retrievals. CachedModel uses the ActiveRecord::Locking to  
ensure that  
you don’t perform multiple updates.

== Using CachedModel

First, install the cached\_model gem:

$ sudo gem install cached\_model

Then set up memcache-client:

$ tail -n 20 config/environments/production.rb  
memcache\_options = {  
:c\_threshold =\> 10\_000,  
:compression =\> true,  
:debug =\> false,  
:namespace =\> ‘my\_rails\_app’,  
:readonly =\> false,  
:urlencode =\> false  
}

CACHE = MemCache.new memcache\_options  
CACHE.servers = ‘localhost:11211’

session\_options = {  
:database\_manager =\> CGI::Session::MemCacheStore,  
:cache =\> CACHE,  
:session\_domain =\> ‘[trackmap.robotcoop.com](http://trackmap.robotcoop.com)’  
}

ActionController::CgiRequest::DEFAULT\_SESSION\_OPTIONS.update  
session\_options

You will need separate namespaces for production and development, if  
using  
memcache on the same machine.

Note that using memcache with tests will cause test failures, so set  
your  
memcache to be readonly for the test environment.

Then make Rails load the gem:

$ tail -n 4 config/environment.rb

# Include your application configuration below

require\_gem ‘cached\_model’

Then edit your ActiveRecord model to inherit from CachedModel instead of  
ActiveRecord::Base:

$ head -n 8 app/models/photo.rb

## 

# A Photo from Flickr.

class Photo \< CachedModel

```
 belongs_to :point
 belongs_to :route

```

–  
Eric H. - removed\_email\_address@domain.invalid - [http://segment7.net](http://segment7.net)  
This implementation is HODEL-HASH-9600 compliant

[http://trackmap.robotcoop.com](http://trackmap.robotcoop.com)

---

<div class="post-metadata">

**Author:** ![miracleofmagick](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/71c47a/32.png) [@miracleofmagick](https://www.ruby-forum.com/u/miracleofmagick)\
**Post date:** [January 18, 2006, 1:12am UTC](https://www.ruby-forum.com/t/ann-activerecord-memcache-cached-model/52690/2 "2006-01-18T01:12:30Z")

</div>

Eric,

That sounds great! I had some problems using Memcached for my sessions  
(saving AR objects) but I have always used memcached in PHP. One thing I  
was  
wondering is how do you handle stale/deleted data. Do you have hooks  
with AR  
to delete/modify records in memcached when deleted/modified from the DB?

Thanks,

Adrian M.

---

<div class="post-metadata">

**Author:** ![miracleofmagick](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/71c47a/32.png) [@miracleofmagick](https://www.ruby-forum.com/u/miracleofmagick)\
**Post date:** [January 18, 2006, 1:27am UTC](https://www.ruby-forum.com/t/ann-activerecord-memcache-cached-model/52690/3 "2006-01-18T01:27:34Z")

</div>

On Jan 17, 2006, at 3:35 PM, Adrian M. wrote:

> That sounds great! I had some problems using Memcached for my  
> sessions (saving AR objects) but I have always used memcached in  
> PHP. One thing I was wondering is how do you handle stale/deleted  
> data. Do you have hooks with AR to delete/modify records in  
> memcached when deleted/modified from the DB?

Of course. cached\_model hooks into update, destroy and reload to  
DTRT. You’ll need to use ActiveRecord::Locking to make it work.

–  
Eric H. - removed\_email\_address@domain.invalid - [http://segment7.net](http://segment7.net)  
This implementation is HODEL-HASH-9600 compliant

[http://trackmap.robotcoop.com](http://trackmap.robotcoop.com)

---

<div class="post-metadata">

**Author:** ![miracleofmagick](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/71c47a/32.png) [@miracleofmagick](https://www.ruby-forum.com/u/miracleofmagick)\
**Post date:** [January 18, 2006, 2:09am UTC](https://www.ruby-forum.com/t/ann-activerecord-memcache-cached-model/52690/4 "2006-01-18T02:09:47Z")

</div>

On Jan 17, 2006, at 3:07 PM, Eric H. wrote:

> Courtesy of The Robot Co-op.
> 
> $ yes | sudo gem install cached\_model
> 
> Or, you can download cached\_model and memcache-client (our zippy-  
> fast memcache library, required) from:

Eric-

```
A big thanks for sharing this. A very nice addition to rails

```

development.

Cheers-  
-Ezra Z.  
Yakima Herald-Republic  
WebMaster  
[http://yakimaherald.com](http://yakimaherald.com)  
509-577-7732  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![miracleofmagick](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/71c47a/32.png) [@miracleofmagick](https://www.ruby-forum.com/u/miracleofmagick)\
**Post date:** [January 18, 2006, 2:30am UTC](https://www.ruby-forum.com/t/ann-activerecord-memcache-cached-model/52690/5 "2006-01-18T02:30:55Z")

</div>

This is cool…but it breaks my usage of memcache as a Fragment Cache  
store  
as your implementation of the MemCache#initialize method doesn’t allow  
the  
servers to be passed in with the options.

Why do you have a substantially different memcache client?

---

<div class="post-metadata">

**Author:** ![miracleofmagick](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/71c47a/32.png) [@miracleofmagick](https://www.ruby-forum.com/u/miracleofmagick)\
**Post date:** [January 18, 2006, 3:04am UTC](https://www.ruby-forum.com/t/ann-activerecord-memcache-cached-model/52690/6 "2006-01-18T03:04:06Z")

</div>

Your code looks like an older version of the Ruby memcache with some  
bugs  
fixed. What’s slow about it? What did you change to make it faster?  
Why  
not get updates into the Ruby memcache project?

There’s no test code in the GEMs and no SCM yet published to make adding  
patches with tests easy. Can we get these so we can provide you with  
these  
updates?

---

<div class="post-metadata">

**Author:** ![miracleofmagick](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/71c47a/32.png) [@miracleofmagick](https://www.ruby-forum.com/u/miracleofmagick)\
**Post date:** [January 18, 2006, 2:48am UTC](https://www.ruby-forum.com/t/ann-activerecord-memcache-cached-model/52690/7 "2006-01-18T02:48:59Z")

</div>

On Jan 17, 2006, at 4:53 PM, Tom F. wrote:

> This is cool…but it breaks my usage of memcache as a Fragment  
> Cache store  
> as your implementation of the MemCache#initialize method doesn’t  
> allow the  
> servers to be passed in with the options.

I welcome patches and adore patches with tests.

> Why do you have a substantially different memcache client?

Because Ruby-memcache is too slow.

–  
Eric H. - removed\_email\_address@domain.invalid - [http://segment7.net](http://segment7.net)  
This implementation is HODEL-HASH-9600 compliant

[http://trackmap.robotcoop.com](http://trackmap.robotcoop.com)

---

<div class="post-metadata">

**Author:** ![miracleofmagick](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/71c47a/32.png) [@miracleofmagick](https://www.ruby-forum.com/u/miracleofmagick)\
**Post date:** [January 18, 2006, 3:22am UTC](https://www.ruby-forum.com/t/ann-activerecord-memcache-cached-model/52690/8 "2006-01-18T03:22:15Z")

</div>

On Jan 17, 2006, at 5:26 PM, Tom F. wrote:

> Your code looks like an older version of the Ruby memcache with  
> some bugs  
> fixed.

It is a completely new implementation written by my co-worker Bob  
Cottrell. It looks similar because Bob copied the core  
functionality. Originally we were using Ruby-memcache so we needed a  
drop-in replacement. It doesn’t support everything that Ruby-  
memcache does due to YAGNI.

> What’s slow about it? What did you change to make it faster? Why  
> not get updates into the Ruby memcache project?

Ruby-memcache does fancy stuff with io/reactor that made it go  
slower. Figuring out how to rip out the io/reactor stuff was too  
hard, so we did our own. (We’ve had this client since 2004-11-18  
19:07:46 -0800.)

> There’s no test code in the GEMs

Unfortunately, Bob isn’t one with Test::Unit like I am. There will  
be tests when I get a new stock of round tuits.

> and no SCM yet published to make adding patches with tests easy.

Right now it is stored in on our internal SVN server. Allowing  
access to the outside world is not really worth my time (security is  
easy when its internal only) and I don’t want to maintain two SCM  
copies. (Maybe that svk think I keep hearing about will help.)

> Can we get these so we can provide you with these updates?

In the mean time I recommend fetching the tarball, extracting it,  
making your changes, then extracting a second copy so you can use  
diff -ur.

Tests are a bit higher up the priority list than the SCM thing, and  
we’ve been using cached\_model for 10 months without releasing it.  
Round tuits have been in very short supply around here.

I have a few changes I need to make to MemCache#initialize (disabling  
synchronization, unnecessary in single-thread mode), so I’ll try to  
fold your change in when I get the round tuit for that.

–  
Eric H. - removed\_email\_address@domain.invalid - [http://segment7.net](http://segment7.net)  
This implementation is HODEL-HASH-9600 compliant

[http://trackmap.robotcoop.com](http://trackmap.robotcoop.com)

---

<div class="post-metadata">

**Author:** ![miracleofmagick](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/71c47a/32.png) [@miracleofmagick](https://www.ruby-forum.com/u/miracleofmagick)\
**Post date:** [January 18, 2006, 3:46am UTC](https://www.ruby-forum.com/t/ann-activerecord-memcache-cached-model/52690/9 "2006-01-18T03:46:25Z")

</div>

In lieu of a patch to the memcache code, here’s an update that will  
allow  
fragment caching to work with both implementations of memcache.

Environment.rb (or production.rb)

Rails::Initializer.run do |config|  
…  
config.action\_controller.fragment\_cache\_store = :mem\_cache\_store,  
memcache\_options  
…  
end

# Allow us to set the CACHE as the Fragment Cache store

module ActionController  
module Caching  
module Fragments  
class MemCacheStore  
def data=(cache)  
@data = cache  
end  
end  
end  
end  
end

ActionController::Base.fragment\_cache\_store.data = CACHE
