Issue
No, we’re not talking about the critter. We’re talking about the fast open source searching tool by Dave Balmain. You know, Ferret. If you need fast indexing and searching, especially if you’re doing Ruby on Rails development, check it out.
Anyway, there’s one funky thing that we’ve come across lately and wanted to share — something that works well when running in development mode but that causes bizarre issues in production mode.
If you’re doing a search like this
query = Ferret::Search::WildcardQuery.new(:name, "tomcat")
it works just fine in development mode, but it’ll fail in production mode.
Trick
Why, you ask? Well, it turns out that in production mode Ferret uses something called DRb (Distributed Ruby) so that it can run as a stand-alone server to work with multiple Rails instances as clients. You can think of DRb as being similar to RMI if you’re from the Java world.
The key is that it has to marshal objects from once instance of Ruby to another, and then un-marshal them in the receiving instance to make them usable again. If the receiving instance doesn’t know about things like Ferret::Search::WildcardQuery you’re out of luck.
What’s so painful about this particular issue is that the error you get when the problem occurs looks like this:
DRb::DRbConnError (DRbServerNotFound):
followed by a giant stack trace.
Server not found? Excuse me? Not exactly what we were expecting.
To make a long story short, there’s an easy way to make all this pain go away, and that’s by simply using FQL, Ferret Query Language, to specify your search.
Instead of creating a WildcardQuery object, you can just define your search the easy way by saying:
query = "name:*tomcat*"
Wow, that sure was easy. Too bad that trying to save some parse time by constructing the object yourself leads to so much aggravation. This way, DRb only has to send a simple string across the wire and all is well.
Maybe next time we’ll just start with the easy solution and see how that works for a change.
