Undefined method `add'

We’ve been running into problems with ferret indexing lately. The
problem is intermittent and some times it persists. Just got this after
wiping the index and redeploying:

NoMethodError (undefined method add' for Solution:Class): (druby://10.1.65.87:9009) /data/releases/20071111152414/vendor/rails/activerecord/lib/active_record/base.rb:1238:inmethod_missing’
(druby://10.1.65.87:9009)
/data/releases/20071111152414/vendor/plugins/acts_as_ferret/lib/ferret_server.rb:71:in
send' (druby://10.1.65.87:9009) /data/releases/20071111152414/vendor/plugins/acts_as_ferret/lib/ferret_server.rb:71:inmethod_missing’

/data/releases/20071111152414/vendor/plugins/acts_as_ferret/lib/remote_index.rb:31:in
`<<’

/data/releases/20071111152414/vendor/plugins/acts_as_ferret/lib/instance_methods.rb:73:in
`ferret_create’

I’m running the latest stable version of AAF. Any tips or work arounds
much appreciated.

Morten

Hi,

I think I’m getting closer to what’s going on with this problem.

Basically, the models that we’re experiencing this with, are subclasses
(Rails STI), such that:

class Entry < AR::Base
acts_as_ferret
end

class Solution < Entry
end

class Notice < Entry
end

The problem may appear intermittently, because the subclassed models
have not been loadeded correctly somehow, and thus confusing ferret. If
I reload the page that causes the problem a few times, things usually
begin working.

I suppose one way to do a quick fix would be to explicity require the
models in one of the initialization files (eg. environment.rb) such that
entry gets required first, and then each of the sub-classes.

I’ll see if I can reproduce this outside of production.

Br,

Morten

Well, that wasn’t it. It appears to happen for top level classes in the
inheritance hierarchy as well and for classes that are not even
subclassed.

It only happens once per class type immediatly after restarting the
Ferret backgroundrb process, after which things begin working.

It does not help to require the classes in environment.rb

Any suggestions?

Thanks.

Morten

On the first request, which breaks, the following gets written to the
ferret_server.log:

call index method: add with [#<DRb::DRbUnknown:0x2a97fd97a8
@name=“Solution”,
@buf="\004\bIC:\025Ferret::Document{\023:\022is_syndicatedF:\

On subsequent requests, the logging looks like this:

call index method: add with [{:account_id=>127, :type=>Solution,
:is_syndicated=>false, :submitter_id=>-1

This means, that the ferret server does not know the type of the object
being indexed on the first request. Is this correct? As far as I can
tell, the object getting sent is a “Ferret::Document” (from the gem). Is
there a way to make AAF always send a hash? Would that make sense?

Morten

Hi Morten,

glad you could make this work for you.

I’m not sure why you’re seeing this strange behaviour, I’ve never seen
this happen before.

Cheers,
Jens

On Mon, Nov 12, 2007 at 03:22:33PM +0100, Morten wrote:

output, reveals:
logger.warn(“Reloaded DRb::DRbUnknown to #{record.class.name}”)
before the relevant classes get loaded in the initial request?


Ferret-talk mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/ferret-talk


Jens Krämer
webit! Gesellschaft für neue Medien mbH
Schnorrstraße 76 | 01069 Dresden
Telefon +49 351 46766-0 | Telefax +49 351 46766-66
[email protected] | www.webit.de

Amtsgericht Dresden | HRB 15422
GF Sven Haubold, Hagen Malessa

The underlying problem is bad unmarshalling of the Ferret::Document that
gets sent to the DRb server.

In ferret_server.rb:

rescue NoMethodError
@logger.debug “no luck, trying to call class method instead”

Using rescue NoMethodError => e and then include e.message in the debug
output, reveals:

undefined method `to_doc’ for #DRb::DRbUnknown:0x2a9808f3f0

I’m pretty blank as to why Ferret::Document does not get properly
unmarshalled on the initial request. If I change the add method to
attempt a DRb reload in local_index.rb (line ~139):

def add(record)
if record.is_a?(DRb::DRbUnknown)
record = record.reload
logger.warn(“Reloaded DRb::DRbUnknown to #{record.class.name}”)
end

record = record.to_doc unless Hash === record || Ferret::Document ===
record
ferret_index << record
end

Then I do indeed get a Document instance back, ie. I have a work around.

But why does this work around work? Does the unmarshalling process occur
before the relevant classes get loaded in the initial request?

I’ll patch up my local AAF to use this work around, but as it does not
solve the actual root problem, I guess it’s not interesting as a patch
submission.

Br,

Morten

This fix did not work for me as the problem was different, but I’m
putting my fix here in case anyone else finds it useful. Our problem
lay with the interaction between acts_as_ferret and
acts_as_taggable_on_steroids:

Putting an object with binary data into:

acts_as_ferret :fields => { :title => {:boost => 10},
:something_binary => {:boost => 3}}

will cause aaf to throw the same error. Using
acts_as_taggable_on_steroids, putting :tag_list into the :fields hash
gave this error. However, putting :tag_list.collect {|tag| tag} works.
Looking in to the aaf code, it attempts to treat the object as a hash
first (which is where it got binary data from for us) and if that
doesn’t work it treats it as an iterable. The change forces it to act
as an iterable. See acts_as_ferret/lib/act_methods.rb lines 240-250.

Cameron.

Jens K. wrote:

Hi Morten,

glad you could make this work for you.

I’m not sure why you’re seeing this strange behaviour, I’ve never seen
this happen before.

Cheers,
Jens

On Mon, Nov 12, 2007 at 03:22:33PM +0100, Morten wrote:

output, reveals:
logger.warn(“Reloaded DRb::DRbUnknown to #{record.class.name}”)
before the relevant classes get loaded in the initial request?


Ferret-talk mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/ferret-talk


Jens Kr�mer
webit! Gesellschaft f�r neue Medien mbH
Schnorrstra�e 76 | 01069 Dresden
Telefon +49 351 46766-0 | Telefax +49 351 46766-66
[email protected] | www.webit.de

Amtsgericht Dresden | HRB 15422
GF Sven Haubold, Hagen Malessa