Libmemcached Store and Passenger.
30 Jun 2010Stemming from the caching issues, I described previously, I decided it was a good opportunity to update our caching implementation. What we had was a hybrid of MemCacheStore for use with fragments and a wrapper around Evan Weaver’s memcached gem for a few other processes. This was a bit quirky, not to mention fragile. Multiple implementations, multiple configurations. Smelly code, for sure.
I’ve worked with other caching frameworks before and while i was loathe to introduce any new complexity, it seemed that the best approach was to unify the two implementations as much as possible. That meant staying away from cache_fu, cache-money, interlock, etc. There’s been a dearth of caching libraries popping up over the past year or so. I suspect that’s because many people are using Rails internal caching. That led me to look at cache_stores, and libmemcached_store from 37 Signals. It was a breeze to implement as a drop-in replacement for MemCacheStore
.
The only catch was, we’re using passenger. I wanted to make sure that LibmemcachedStore played nice with passenger’s spawning process. Here’s how to do it:
if defined?(PhusionPassenger)
PhusionPassenger.on_event(:starting_worker_process) do |forked|
if forked
# We're in smart spawning mode.
Member.connection.reconnect!
Rails.cache.instance_variable_get(:@cache).quit if Rails.cache.class == ActiveSupport::Cache::LibmemcachedStore
else
# We're in conservative spawning mode. We don't need to do anything.
end
end
end
It’d be nice if all cache stores implemented a reset or disconnect method, in the meantime, we have hacks like this.