A while back, I tweeted about how cool it was to have a software patch I submitted be accepted.

You know what’s cooler than that?

Realizing that someone is actually using a plugin I wrote.

I mean, working with open source, when you put something like that out there, it’s with the idea that people will use it. But having the idea is a lot different from the realization that someone you’ve never met half way around the world found something you did to be useful.

Edited to add: I just realized that it might not be obvious from the link, but I’m talking about the db_free_solr plugin.

one

I know, I know. No one uses Solr anymore. Except me. And the guy that maintains acts_as_solr. And all those people who talk about it on twitter. Okay, so there are still a few people using it. This is for them.

Just a quick note on how you can improve your user’s browsing experience in an app that uses acts_as_solr. Our app has been using acts_as_solr for a year or more now, and we’ve generally been happy with it. Re-indexing a big table can be painful, but we don’t really end up doing that very often.

The one area that was still causing us some pain was the inline indexing of objects. I think the standard solution for this issue has been to defer indexing when creating/updating/deleting and have a cron job scheduled to take care of it at regular intervals. And that both works and is relatively painless. But that solution negates one of the things I like about acts_as_solr, as compared to other search solutions, which is the fact that indexing can be real time.

Anyway, I’m getting a little long winded, all I wanted to do here was point out something that, in retrospect, might seem obvious to others.

Recently, for reasons unrelated to Solr, we implemented workling and starling so that we could background some tasks that were delaying (and in some cases, timing out) our users’ sessions. While I was working on it, I realized that we could use workling to background the inline solr indexing, allowing us to speed up save operations while still basically having real time indexing. Here’s how we did it (all of this assumes that you have workling installed and functioning):

First, we created app/workers/solr_worker.rb:

class SolrWorker < Workling::Base
 
  def index_object(options={})
    object = options[:object_type].constantize.find_by_id(options[:object_id])
    unless object.blank?
      object.solr_save
    end
  end
 
  def destroy_object_index(options={})
    object = options[:object_type].constantize.find_by_id(options[:object_id])
    unless object.blank?
      object.solr_destroy
    end
  end
 
end

Next, in vendor/plugins/acts_as_solr/lib/instance_methods.rb, we added two methods:

def async_solr_save
  SolrWorker.async_index_object(:object_type => self.class.name, :object_id => self.id)
end
 
def async_solr_destroy
  SolrWorker.async_destroy_object_index(:object_type => self.class.name, :object_id => self.id)
end

And, finally, in vendor/plugins/acts_as_solr/lib/acts_methods.rb, we changed two lines from this:

after_save    :solr_save
after_destroy :solr_destroy

To this:

after_save    :async_solr_save
after_destroy :async_solr_destroy

And that’s it. This solution has been in place for a couple of weeks now, and we’ve seen a real improvement.

none

Categories

Links

Most commented