:jasonrudolph => :blog

puts Blog.new(”nonsense”)

Podcast Interview with aboutGroovy.com: The Sequel

Posted by Jason Rudolph on 4th February 2008

It’s been almost a year since I first sat down with Scott Davis for an aboutGroovy.com interview, and the upcoming Groovy/Grails Experience seemed as good a reason as any for us to catch up.

2008-02-04 aboutGroovy.com

In addition to discussing the various conference sessions in the works, we also spend a few moments exploring some relative merits of Rails and Grails. While we won’t tell you which framework is right for you, I do suggest some key features that each framework could stand to adopt from the other, and we even discuss how some of that cross-pollination is already coming to fruition.

Many thanks to Scott for having me on the podcast.

Download the MP3 directly

or

Subscribe to aboutGroovy.com podcasts via RSS

Tags: , , , , , | No Comments »

Making acts_as_solr Act As Deployable

Posted by Jason Rudolph on 26th November 2007

We recently deployed two new Solr-powered apps, and thanks to acts_as_solr, most of the task of integrating Solr with Rails was downright trivial. Deployment, however, came with a few small roadbumps.

Solr

Know when to nohup

When using acts_as_solr locally, you start and stop Solr via the provided rake tasks (i.e., rake solr:start and rake solr:stop). However, when you run the solr:start task, you’ll quickly notice that all of the would-be log output is right there in your face, and definitely not in some well-tucked-away log file. During development, we didn’t think too much of it. Just open a new terminal tab, start Solr, and get back to devving.

But then came time for deployment. Try to run the vanilla solr:start task as part of a Capistrano deployment, and you’ll quickly be looking for another option. As you watch your deploy script run, here comes all that same output you’ve been seeing locally … but when Cap completes, Solr calls it quits. We need a way to tell Solr to keep running in the background, even after Cap finishes doing its thing.

  1. nohup rake solr:start > #{shared_path}/log/solr.log 2> #{shared_path}/log/solr.err.log

 
(Incidentally, you may want to employ this solution for your local Solr instance as well. After all, that’ll be one fewer terminal window cluttering your workspace.)

Dude, where’s my index?

Now that you have a reliable means for starting and stopping Solr, it’s time to decide where you want to store your index files. By default, acts_as_solr defines SOLR_PATH as #{RAILS_ROOT}/vendor/plugins/acts_as_solr/solr, which means that Solr will store your index files in #{RAILS_ROOT}/vendor/plugins/acts_as_solr/solr/#{RAILS_ENV}/solr/data/#{RAILS_ENV}/index. If you keep that setup, what happens when you deploy a new release of your app? You guessed it: your index files get left behind with the old release.

But that’s almost certainly not the behavior you want. The index files represent data, not application code. You don’t move your database every time you deploy a new release, and you shouldn’t move - or even worse, recreate - your Solr indexes with every release either. (Yes. Just as some releases require database changes, so will some releases require reindexing. But, it’s definitely not a need for every release, and it therefore shouldn’t be your normal practice.)

At this point, you have a few choices, but the goal with each choice remains the same: find a home for the Solr indexes to allow them to survive across multiple deployments. First, copy #{RAILS_ROOT}/vendor/plugins/acts_as_solr/solr to a release-independent location in your deployment environment. Then, you just need to tell your application where to find that directory. Ultimately, SOLR_PATH needs to point to that location. If you don’t want to change the default acts_as_solr settings, then you can configure your deployment script to symlink the copied directory into the location where acts_as_solr expects to find it (i.e., #{RAILS_ROOT}/vendor/plugins/acts_as_solr/solr). Otherwise, you can simply change the definition of SOLR_PATH (defined in #{RAILS_ROOT}/vendor/plugins/acts_as_solr/config/environment.rb) to point to your release-independent directory.

Know your role

Now you have a home for our Solr indexes and you have an easy way to start and stop Solr via Capistrano, but where exactly should Solr itself run? We all want highly performant apps, so you may be tempted to consider running Solr on multiple servers. More is always better. Right?

STOP!

Your app communicates with Solr via HTTP, so Solr can live anywhere on your network. It doesn’t need to live on the same box as your app, as your database, etc. And while you technically could run Solr on all your app servers, it’s highly unlikely that you’ll want to do so. Think about the problems associated with managing redundant databases. Do you really want to manage multiple sets of Solr indexes and try to make sure they all have the same data? Unless you’re Google - in which case, this stuff is your bread and butter - of course not.

If you store the indexes in a shared location and have all the Solr servers use the same indexes, does that make things any easier? Well, you no longer have to keep multiple indexes in sync, but you now have a different problem: data corruption. Solr isn’t designed to share indexes among multiple Solr processes, and when two processes try to update the same indexes, you’re in for all kinds of trouble. UPDATE: Solr isn’t designed to have multiple Solr processes updating a shared set of indexes. (As Hoss points out in the comments, Solr is capable of supporting a distributed installation, but all changes are routed to a single master Solr instance, and multiple query slaves receive the updates from the master.)

So let’s steer clear of all that trouble and find an easy way to run Solr on a single server, while having all your app servers talk to that Solr instance. First up, define a distinct role for the server where you want Solr to run.

  1. task :production do
  2.   role :web, ‘app.example.com’
  3.   role :app, ‘app.example.com’
  4.   role :solr, ’solr.example.com’
  5.   role :db, ‘db.example.com’
  6. end

 

Next, simply define the tasks needed to start and stop Solr on that server, and you’re good to go. (Also notice that we include a task to symlink in the Solr indexes from the release-independent directory discussed above.)

  1. before "deploy:update_code", "solr:stop"
  2. after "deploy:symlink", "solr:symlink"
  3. after "solr:symlink", "solr:start"
  4.  
  5. namespace :solr do
  6.   desc "Link in solr directory"
  7.   task :symlink, :roles => :solr do
  8.     run <<-CMD
  9.       cd #{release_path} &&
  10.       ln -nfs #{shared_path}/solr #{release_path}/solr
  11.     CMD
  12.   end
  13.  
  14.   desc "Before update_code you want to stop SOLR in a specific environment"
  15.   task :stop, :roles => :solr do
  16.     run <<-CMD
  17.       cd #{current_path} &&
  18.       rake solr:stop RAILS_ENV=#{env}
  19.     CMD
  20.   end
  21.  
  22.   desc "After update_code you want to restart SOLR in a specific environment"
  23.   task :start, :roles => :solr do
  24.     run <<-CMD
  25.       cd #{current_path} &&
  26.       nohup rake solr:start RAILS_ENV=#{env} > #{shared_path}/log/solr.log 2> #{shared_path}/log/solr.err.log
  27.     CMD
  28.   end
  29. end

 

And with that little bit of setup, you’re ready to rock! (Well, er, as much as one can rock to full-text search.)

If you want full-text search in your Rails app, definitely take acts_as_solr for a spin. You’ll be up and running in no time, and chances are your users will love the new dimension that full-text search brings to your application.

Looking ahead

As for us, now that these apps are live and flexing all their Solr might, we’re on to looking for ways to make them better, faster, stronger. Long term, we definitely don’t want to maintain the default behavior of synchronously waiting for acts_as_solr to make the call to Solr (in order to update the indexes) each time we save a Solr-enabled ActiveRecord model object. In our apps, it’s more important that we quickly save the object and provide a prompt response back to the user. If it then takes a few seconds of background processing before that change is reflected in Solr, that’s perfectly acceptable (and much preferred over causing the user to wait for us to update the Solr indexes). At least one open source project is already dedicated to mitigating this issue, and we hope to explore this and various asynchronous solutions in the near future.

Tags: , | 2 Comments »

Relevance is Hiring!

Posted by Jason Rudolph on 3rd November 2007

Smart developers. Really.

Working together.

In small teams.

Using the best tools available.

Embracing true agility.

Pushing each other.

And giving back.

In the constant pursuit of excellence.

Relevance

Are you in?

Then check us out.

And let’s hear it: jobs@thinkrelevance.com

Tags: , , , , | No Comments »

Streamlined 0.9 Released - Stop banging rocks together and build something!

Posted by Jason Rudolph on 13th September 2007

Streamlined 0.9 is now available for download. From the rich and handy quick-add interface to the super-flexible and highly-interactive advanced filtering, this release packs a big punch in terms of quickly empowering your end users with a serious data management interface. In addition to introducing the aforementioned heavy hitters, it also makes standard many common idioms to increase the overall usability of your apps (e.g., auto-labeling for required fields) and offers some optional usability enhancers (mmmm, tasty breadcrumbs) as well.

Of course, those are just some of the many improvements available in Streamlined 0.9. Be sure to check out the release notes for full details, including screen shots and links to additional docs.

As we approach 1.0, Streamlined continues to position itself as the solution for developing an instant, production-ready UI for your ActiveRecord models. So, what are you waiting for? Stop banging rocks together and build something!

Tags: , , | 2 Comments »

Streamlining Your Way to Rails

Posted by Jason Rudolph on 24th June 2007

By the time you’ve knocked out your first few Rails apps, you’re probably not particularly excited about starting another UI from scratch. You’re still jazzed about the fact that ActiveRecord is going to save you from all the boilerplate ORM plumbing, and you’re psyched to be developing in a dynamic (and elegant and powerful) language like Ruby, but it’s hard to actually look forward to manually wiring up the relationships in the UI (again), tediously tying in Ajax in all the usual places (again), implementing live search (again), adding in pagination and sortable lists (again), and, well, you get the idea. Developing in Rails is supposed to be enjoyable, so we need something to bring the overall pleasantness of Rails into these areas of application development as well.

Enter Streamlined

Read the rest of this entry »

Tags: , , , | No Comments »

JavaOne Day 4, Part 1: Where Do Standards Come From?

Posted by Jason Rudolph on 13th May 2007

The fourth and final day of JavaOne: it was a big one. Here we go…

Comparing the Developer Experience of Java EE 5.0, Ruby on Rails, and Grails: Lessons Learned from Developing One Application

Presented by Tom Daly (Senior Performance Engineer at Sun Microsystems) and Damien Cooke (ISV Engineering at Sun Microsystems)

Having spent many years now developing applications in the JEE space, and having had a good look at Rails before spending the past year working with Grails, I was eager to see whether others have drawn the same conclusions as I have. It’s a time-tested technique to loosen up the crowd with a joke, and when I heard Tom’s opening line - “I don’t know much about Ruby and I don’t know much about Groovy” - I was a bit concerned. It wasn’t meant to be a joke. Yet somehow, in just 60 minutes, they actually managed to pull off a pretty darn fair comparison of the three frameworks.

Read the rest of this entry »

Tags: , , | No Comments »

JavaOne Day 3, Part 1: Mash-up your languages, Mash-up your web apps

Posted by Jason Rudolph on 11th May 2007

The variety of topics at this year’s JavaOne has been quite impressive, and Day 3 was no exception. Ruby, JavaScript, Groovy, Spring, and JMX all in one day? You bet. Here goes.

JRuby on Rails: Agility for the Enterprise

Presented by Thomas Enebo and Charles Oliver Nutter (JRuby Core Developers)

Charlie and Tom referred to this session as a chance to see “how the other 8% lives,” and not surprisingly, this talk saw a fair amount of traffic. When they polled the audience though, it was quite interesting to see that more folks had heard of Rails than had heard of Ruby. (I imagine the Ruby veterans find that bit of trivia to be a bit annoying.)

Read the rest of this entry »

Tags: , , , | No Comments »