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