I am using Memcached as an Object Store with my Rails application where I store search results which are User objects in memcached
Now when I fetch the data out I get the Memcached Undefined Class/Module Error. I found a solution for this problem in this blog
http://www.philsergi.com/2007/06/rails-memcached-undefinded-classmodule.html
before_filter :preload_models
def preload_models
Model1
Model2
end
which recommends pre-loading the models before hand. I would like to know if there is a more elegant solution to this problem and are there any drawbacks in using the preloading technique.
Thanks in advance
I had this problem as well and I think i came up with a nice solution.
You can overwrite the fetch method and rescue the error and load the right constants.
module ActiveSupport
module Cache
class MemCacheStore
# Fetching the entry from memcached
# For some reason sometimes the classes are undefined
# First rescue: trying to constantize the class and try again.
# Second rescue, reload all the models
# Else raise the exception
def fetch(key, options = {})
retries = 2
begin
super
rescue ArgumentError, NameError => exc
if retries == 2
if exc.message.match /undefined class\/module (.+)$/
$1.constantize
end
retries -= 1
retry
elsif retries == 1
retries -= 1
preload_models
retry
else
raise exc
end
end
end
private
# There are errors sometimes like: undefined class module ClassName.
# With this method we re-load every model
def preload_models
#we need to reference the classes here so if coming from cache Marshal.load will find them
ActiveRecord::Base.connection.tables.each do |model|
begin
"#{model.classify}".constantize
rescue Exception
end
end
end
end
end
end
Ran across this today, managed to come up with a more terse solution that should work for all classes.
Rails.cache.instance_eval do
def fetch(key, options = {}, rescue_and_require=true)
super(key, options)
rescue ArgumentError => ex
if rescue_and_require && /^undefined class\/module (.+?)$/ =~ ex.message
self.class.const_missing($1)
fetch(key, options, false)
else
raise ex
end
end
end
Not sure why [MemCacheStore]
is not having is [MemCacheStore.const_missing]
method called and everything getting called in the normal “Rails-y” way. But, this should emulate that!
Cheers,
Chris
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With