This topic is related to the one I created yesterday (http://
groups.google.com/group/acts_as_cached/browse_thread/thread/
20c03f1bcbc625b1), resolved by Chris.
I'm using acts_as_cached to cache GalleriesLists. Galleries are
submitted by Users.
I'm writing things like this:
# --- CODE ---
class GalleriesList < ActiveRecord::Base
acts_as_cached
PAGES_IN_CACHE = 5 # number of pages to add to cache
def self.find(id)
my_params = id.split("_")
from_page = my_params[0]
current_page = my_params[1].to_i
items_per_page = my_params[2].to_i
user_filter = my_params[3].to_i
@paginator = Hash.new
case from_page
# (... setting @paginator options)
end
Gallery.find(:all, :conditions =>
@paginator['conditions'], :include => @paginator['include'], :order =>
@paginator['order'], :limit => @paginator['limit'], :page => { :size
=> @paginator['items_per_page'], :current => current_page, :first =>
1 }) # --> using paginating_find
end
def self.get_cache(from_page, current_page)
if current_page < PAGES_IN_CACHE
super("#{from_page}_#{current_page}_#{User.current_user.items_per_page}_#{User.current_user.filter}")
# (line 151)
else
find("#{from_page}_#{current_page}_#{User.current_user.items_per_page}_#{User.current_user.filter}")
end
end
end
# --- /CODE ---
In my controller, i'm getting galleries like this:
# --- CODE ---
@galleries = GalleriesList.get_cache(from_page, current_page) #
(line 97)
# --- /CODE ---
And here is the error I'm getting:
# --- CODE ---
TypeError (no marshal_dump is defined for class Proc):
/usr/lib/ruby/gems/1.8/gems/memcache-client-1.3.0/lib/memcache.rb:
292:in `dump'
/usr/lib/ruby/gems/1.8/gems/memcache-client-1.3.0/lib/memcache.rb:
292:in `set'
/vendor/plugins/acts_as_cached/lib/acts_as_cached.rb:251:in
`set_to_cache'
/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.2/lib/active_support/
core_ext/object/misc.rb:23:in `returning'
/vendor/plugins/acts_as_cached/lib/acts_as_cached.rb:249:in
`set_to_cache'
/vendor/plugins/acts_as_cached/lib/benchmarking.rb:8:in
`cache_benchmark'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/benchmarking.rb:37:in `silence'
/vendor/plugins/acts_as_cached/lib/benchmarking.rb:8:in
`cache_benchmark'
/usr/lib/ruby/1.8/benchmark.rb:293:in `measure'
/usr/lib/ruby/1.8/benchmark.rb:307:in `realtime'
/vendor/plugins/acts_as_cached/lib/benchmarking.rb:8:in
`cache_benchmark'
/vendor/plugins/acts_as_cached/lib/acts_as_cached.rb:248:in
`set_to_cache'
/vendor/plugins/acts_as_cached/lib/acts_as_cached.rb:209:in
`get_and_set_cache'
/vendor/plugins/acts_as_cached/lib/acts_as_cached.rb:193:in
`get_cache'
/app/models/galleries_list.rb:151:in `get_cache'
/app/controllers/application.rb:97:in `get_galleries'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:456:in `call'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:435:in `call'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:637:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:638:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:438:in `call'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:637:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:638:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:438:in `call'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:637:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:638:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:438:in `call'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:637:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:634:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:638:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:438:in `call'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:637:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:634:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:638:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:600:in `proxy_before_and_after_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:470:in `call'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:637:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:638:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:438:in `call'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:637:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:638:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:438:in `call'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:637:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:638:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:438:in `call'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:637:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:638:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:438:in `call'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:637:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:638:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:438:in `call'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:637:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:638:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:449:in `call'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:637:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:638:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:449:in `call'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:637:in `call_filter'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:619:in `perform_action_without_benchmark'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/benchmarking.rb:66:in
`perform_action_without_rescue'
/usr/lib/ruby/1.8/benchmark.rb:293:in `measure'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/benchmarking.rb:66:in
`perform_action_without_rescue'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/rescue.rb:83:in `perform_action'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/base.rb:430:in `process_without_filters'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/filters.rb:624:in
`process_without_session_management_support'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/session_management.rb:114:in `process'
/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/
action_controller/base.rb:330:in `process'
/usr/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/dispatcher.rb:41:in
`dispatch'
/usr/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel/rails.rb:
78:in `process'
/usr/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel/rails.rb:
76:in `process'
/usr/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel.rb:618:in
`process_client'
/usr/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel.rb:617:in
`process_client'
/usr/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel.rb:736:in
`run'
/usr/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel.rb:736:in
`run'
/usr/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel.rb:720:in
`run'
/usr/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel/
configurator.rb:271:in `run'
/usr/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel/
configurator.rb:270:in `run'
/usr/lib/ruby/gems/1.8/gems/mongrel-1.0.1/bin/mongrel_rails:127:in
`run'
/usr/lib/ruby/gems/1.8/gems/mongrel-1.0.1/lib/mongrel/command.rb:
211:in `run'
/usr/lib/ruby/gems/1.8/gems/mongrel-1.0.1/bin/mongrel_rails:243
/usr/bin/mongrel_rails:18
# --- /CODE ---
When, in my GalleriesList model, I replace:
# --- CODE ---
Gallery.find(:all, :conditions => @paginator['conditions'], :include
=> @paginator['include'], :order => @paginator['order'], :limit =>
@paginator['limit'], :page => { :size =>
@paginator['items_per_page'], :current => current_page, :first => 1 })
# --- /CODE ---
... by:
# --- CODE ---
Gallery.find(:all, :conditions => @paginator['conditions'], :include
=> @paginator['include'], :order => @paginator['order'], :limit =>
@paginator['limit'])
# --- /CODE ---
... I don't get the error. So it seems paginating_find is in trouble
with acts_as_cached. Do you have any idea about what is happening?
Cheers,
Michael
The paginating_find plugin uses a proc to load pages on demand. If I
understand correctly, memcached cannot cache procs. If you're caching
the return value of the #find method, this would explain the error
you're getting.
Could you just use the plugin to load the requisite page and then
cache it using the return value of the @page#to_a method? In other
words, just call #find(...).to_a. That way you aren't caching the
plugin's special enumerator, but rather an array of galleries.
-Alex
> super("#{from_page}_#{current_page}_#{User.current_user.items_per_page}_#{U ser.current_user.filter}")
> # (line 151)
> else
>
> find("#{from_page}_#{current_page}_#{User.current_user.items_per_page}_#{Us er.current_user.filter}")
> ... I don't get the error. So it seemspaginating_findis in trouble
>> Gallery.find(:all, :page => { :size => 10, :current => 1, :first => 1})
=> #<PagingEnumerator:0xb76514b0 @auto=false, @page_count=40,
@page_size=10, @callback=#<Proc:0xb732cf00@./script/../config/../
config/../vendor/plugins/paginating_find/lib/paginating_find.rb:75>,
@first_page=1, @size=397, @stop_page=1, @page=1, @last_page=40>
So, I can see where the Proc object comes from (the error I'm getting
is "no marshal_dump is defined for class Proc").
Cheers,
Michael
It's a marshal issue. Since acts_as_cached uses Marshal to serialize
Ruby objects for memcached, it just ain't gonna happen. Any ideas on
workarounds?
The general fix is: don't cache things with procs. I suppose you
could override that particular class' set_cache to clear the instance
variable which is a proc, or something, before setting it to
memcached, but that all depends on how badly you need that proc and
whether or not it's something that can be re-added on get_cache.
--
Chris Wanstrath
http://errfree.com // http://errtheblog.com
Well, I think the cache should be set to @galleries.to_a, which is the
Galleries list. @galleries contains the Proc and should not be cached,
it's a PagingEnumerator object.
My GalleriesList.find method should look like this:
def self.find(id)
# (... splitting id into params and setting my @paginator
options ...)
@galleries = Gallery.find(:all, :conditions =>
@paginator['conditions'], :include => @paginator['include'], :order =>
@paginator['order'], :limit => @paginator['limit'], :page => { :size
=> @paginator['items_per_page'], :current => current_page, :first =>
1 })
@galleries.to_a
end
So the cache should be OK. But my new problem is that I need
@galleries (the PagingEnumerator object) in my controller. When I call
it in my controller, it's nil. Do you know how I can retrieve it?
Cheers,
Michael
On Apr 25, 2:00 am, "Chris Wanstrath" <c...@ozmm.org> wrote:
> >> something = proc { "something" }
>
> => #<Proc:0x021ae79c@(irb):1>>> Marshal.dump(something)
>
> TypeError: no marshal_dump is defined for class Proc
> from (irb):2:in `dump'
> from (irb):2
>
> It's a marshal issue. Since acts_as_cached uses Marshal to serialize
> Ruby objects for memcached, it just ain't gonna happen. Any ideas on
> workarounds?
>
> The general fix is: don't cache things with procs. I suppose you
> could override that particular class' set_cache to clear the instance
> variable which is a proc, or something, before setting it to
> memcached, but that all depends on how badly you need that proc and
> whether or not it's something that can be re-added on get_cache.
>
> So the cache should be OK. But my new problem is that I need
> @galleries (the PagingEnumerator object) in my controller. When I call
> it in my controller, it's nil. Do you know how I can retrieve it?
I don't know, someone might. I'd open a bug with your paginator's
creator asking for Marshal.load/dump compatibility. Or, use
will_paginate ;)
Try updating your plugin now. PagingEnumerator serialization should
now be supported. Shoot me an email if you have any trouble.
-Alex
P.S. Sorry if this message comes through twice. I'm not sure if my
last one made it through.