"no marshal_dump is defined for class Proc" error with paginating_find

273 views
Skip to first unread message

Michael Hulet

unread,
Apr 24, 2007, 5:38:29 AM4/24/07
to acts_as_cached
Hi all,

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

Alex Wolfe

unread,
Apr 24, 2007, 11:18:23 AM4/24/07
to acts_as_cached
Hi 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

Michael Hulet

unread,
Apr 24, 2007, 8:31:20 AM4/24/07
to acts_as_cached
I have more information using the Ruby console:

>> 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

Chris Wanstrath

unread,
Apr 24, 2007, 8:00:11 PM4/24/07
to acts_as...@googlegroups.com
>> 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.


--
Chris Wanstrath
http://errfree.com // http://errtheblog.com

Michael Hulet

unread,
Apr 25, 2007, 4:18:48 AM4/25/07
to acts_as_cached
Thanks for answers.

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.
>

Chris Wanstrath

unread,
Apr 26, 2007, 3:42:49 AM4/26/07
to acts_as...@googlegroups.com
On 4/25/07, Michael Hulet <mic...@mindtheshark.com> wrote:

> 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 ;)

Alex Wolfe

unread,
Apr 27, 2007, 11:57:56 AM4/27/07
to acts_as_cached
Michael,

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.

Reply all
Reply to author
Forward
0 new messages