Archive for the ‘Help’ Category

When and Where to use Caching In Rails

Tuesday, May 11th, 2010

(Alternative title to this post: Rails Caching Enlightenment Through Perl)

This entire post will either make you think I’m a horrible web programmer, or hopefully, show you the deep and meaningful insights that I’ve managed to eke out from the experience.

Server Crashes Are Bad
Last night I was up coding, but sadly, not rails code. Yesterday I had a call from a client telling me that the website had crashed, and their clients were pissed off because this happened just when they had put out their weekly newsletter. The server (a virtual hosted system hosted at GoDaddy) had locked up tight, rendering all the sites that were on the server un-reachable.

The server was rebooted, and digging into it there was no clear reason why it had crashed, which is of course not what they wanted to hear. I had a development server set up at home, so I did a bit of testing to see if I could duplicate it. The server was old and slow (not even dual core), but usable as a Linux workstation, so I figured that if I could make the site feel faster here, the gains on the production server would be huge.

Determining A Baseline
First was to hit it with the trusted Apache Benchmark utility, I started with a perfectly reasonable 10 concurrent connections for 1000 hits hitting the landing page that was sent out in the newsletter, and probably one of the more intensive pages DB and logic wise on the site.

$ ab -c 10 -n 1000 “http://site.com/page.html?id=117”

Looking at my system monitor, I immediately saw my CPU use jump to 100%, disk access go from a blip here and there to constant, and the machine ground to a halt.

I hit ctrl-c pretty fast.

OK, problem found, the site is a vampire and sucks the life out of the server. I played with a few different settings and eventually ended up using 5 concurrent connections and 20 hits “-c 5 -n 20” which gave me an average 2000-4000ms to serve pages, about 1 request a second.

Horrible right? Before you put me against the wall to keep me from doing any web programming again, remember this is a really old server. Please? Maybe one smoke before it’s time for me to go?

Small Fixes, Small Gains
So there were three things that I figured I needed to look at:

  1. Use the YSlow plugin to find some small gains
  2. Finally see if there are any just bad code that could be refactored out, loops within loops, useless re-calculation, etc.
  3. Re-examine the number of queries going on on the page

YSlow gave me a few things to do. Setting the expires header for images, moving CSS and JS to the top and bottom of the page, and a couple of other minor things that gave me no real gains via ab.

Surprisingly, there weren’t any low hanging fruit for bad code or useless loops within loops. This sucked, mostly because that meant me going through and re-looking at SQL and refactoring that, which I’m not sure about you, but that doesn’t sound like fun to me.
Somewhat more surprisingly there were only a couple of extra queries, mostly related to the ORM I was using, Class::DBI and some just silly things. Sadly none of these gave me any more gains.

One thing I did find was where the issues were. When I commented out the main grid of items that is the focus on the page, the page response went from 2000-4000ms response time to 200. Hmm…, so what to do with this. What if I could make it so the time to generate the main product grid didn’t happen? So I commented out the dynamic code, and copied in the HTML produced (from the view source window in firefox) to see if it was the dynamic generation (which wasn’t really that complex from what I could see). Again, 200-400ms time, serving 9-10 requests a second, with almost no CPU or disk impact.

OK, so I thought what if there was a way to pre-generate the HTML periodically, and then have the perl code load that instead of doing it dynamically each time. That almost sounds like….. “caching“. Huh, almost like something that should be built in.

Enter Caching
Honestly my experiences with caching have been minimal, most of the time I am trying to prevent caching (for re-uploaded images with the same filename, that sort of thing), and also it just hadn’t come up yet, probably because most of the sites I have worked on don’t get huge enough traffic to require it. Luckily I had just read something about Caching in the HTML::Mason developer docs while finding some information for something else.

HTML::Mason has the concept of “components”, similar to partials in the rails world. You’d call something like this:

blah blah
< & "/comp/gallery.mc", id => $id, page => $cur_page, title => "TiR" &>
blah blah

When the page is rendered it would call the gallery.mc component with the given arguments, render it, running whatever code is in there (HTML::Mason isn’t the nice separated MVC that Rails is, so there’s potentially lots of controller code in your pages and components) and replacing the < & &> with the output. The documents have a nice section on the built in page and component (think fragment) caching where all you need to do is to add this code to the top of your component’s “init” section:

return if $m->cache_self(key => 'fookey', expires_in => '3 hours', [other options...] );

This lets your component see if it’s already in the cache, and not expired, and if it is, serves that, and if not, renders and then caches itself with the given key. The only tricky part is figuring out the right cache key to ensure it’s unique for each section of code. I ended up writing something like this:

$key = "gallery|$id|$cur_page|$title";
return if $m->cache_self(key => $key, expires_in => '10 minutes', [other options...] );

This makes the cache key a hash of the arguments sent to the component, ensuring that each differently rendered version of the page will get a different cache key. Not perfect I’m sure, but a nice mix of good caching and safety.

Running ‘ab’ again I found that while the first couple of requests still took 2000-4000ms to run, subsequent pages were served in the 200-400ms range, and the CPU and disk load was way down.

WTF – This is a Rails Blog
So why am I telling you all this Perl stuff? It’s because this is related more to web programming and programmer mindset than Perl or HTML::Mason. You could replace “perl” with “ruby”, “component” with “partial” and “HTML::Mason” with “Rails” and get the same idea.

Because everything ran fine when the site was under development and only two or three people were hitting it I didn’t have to worry about caching or performance issues. In fact, I didn’t even think about performance because thigns “just worked”. When things did go badly (again, server crashes == pissed off clients), I had to scramble to find a solution (luckily only one night of work).

I’m still doing testing with the new caching code, but I expect to put it online tonight or tomorrow, and look forward to the before and after numbers on the production server.

Lessons Learned
My lessons learned:

  • Watch from the start for cachable pieces of code. Big complex SQL queries or complex logic that can be created once a week, day or even every minute is a candidate. In Rails it can be as simple as surrounding the code with < % cache do %> .. < % end %>.
  • Test performance from the onset. Learn to love Apache Benchmark and start hitting your sites potential hot pages from the start, and watch and learn what causes reponsiveness to go down.

Resources
For those of you wanting some actual rails resources to learn more about this stuff, have a look at the following:

  • Understanding ‘ab’ results – Nice resource for how to read that output.
  • Caching with Rails – The rails guides documentation with details on page, fragment, action caching and everything in between.
  • Rails 2.1 Caching – A bit older, but a nice list of the caching capabilities introduced and available in Rails 2.1, still pretty relevant.
  • The Scaling Rails Podcast Series – Fantastic information in here, I recommend watching all of them, if you can’t, hit #2, 3, 5, 6, 7 for caching, and then #15 and 16 for load testing with ab and friends.
Any other resources or hints as to how to deal with caching in Rails (or Perl for that matter! :) ?

Anatomy of A Ruby Gem

Thursday, May 6th, 2010

If you’ve ever installed a Ruby gem off of gemcutter or github, you’ll know that you run the gem install <gemname> command and when it’s completed you magically have access to use it through ‘require <gemname>’.  If you’ve ever looked into the source you might want to have an idea of what goes where and how it all works.

First of all, I’m fairly new to this myself, so it’s very possible that I’ll miss something vital, please feel free to flame me in the comments, as long as you tell me where I messed up so I can fix it :)

(more…)

Ruby on Rails Lingo For Beginners

Thursday, April 29th, 2010

One of the more challenging things starting out in a new language is having to not only learn the new language/framework, but dealing with the jargon that goes along with it.  There’s nothing more frustrating than finding someone willing to answer your questions, but you can’t understand what they’re saying!  Here’s a few of the acronyms and terms that you might come across if you’re a Ruby on Rails newbie, with a perl refugee slant.

  • Gem – The basic distribution of most of the plugins and addon libraries for Ruby.  Thing CPAN.  A lot of times you can either install a gem onto your system or as a plugin to a rails project.  The basics are you can run “gem list”, “gem install <gem>” and “gem search –remote <search>” to list installed gems, install a new gem by name, or search the configured remote gem servers.  Speaking of CPAN, the main two places for gems (currently anyway) are github and rubygems.  The main rubygems distribution is essential to get most of the gem functionality, so you’ll need to make sure you have the rubygems package (for your OS) installed and working before you can start doing “gem install” all crazy like.  More information can be found on the rubygems site.
  • TDDTest Driven Development.  Ruby and Rails people love testing.  They love it like mom’s homemade pasta and meatballs served to you with lots of Parmesan cheese after a long day. The TDD philosophy basically means that before you write code, you write a test.  In the simplest “hello world” case you would write a test to say “does the program print out ‘hello world’”.  It of course fails because there is no program written yet.  Then you write the code and work on it until it prints out “hello world” and the test passes.  Some people follow TDD to extremes, some ignore it completely (but shouldn’t) and others work in the grey area in between extremes.
  • Waterfall – The waterfall model is another design philosophy, but this is more of the old school, not web 2.0, evil-used-by-suits philosophy.  It’s your classic “wait till Bob gets the requirements done, then we need the architect team to design the models and system, then we’ll get you to implement it, it’ll head into QA for them to test, and eventually it’ll go into maintenance mode”.  Yawn.  That’s not to say that there aren’t good reasons to use this model, but it’s considered an old school way of doing things.  You’ll know what your mentor means and not think he’s talking about a trip to look at waterfalls anyway.
  • DHH – This of course is the creator of Rails, David Heinemeir Hansson.  You might also hear names like Obie Fernandez, Wayne Seguin, and JEG2 (James Edward Gray II), and these too are people high up in the community.  There are a lot of them, and it’s a big community, so don’t feel too bad if you don’t recognize a name or two.
  • MVC – The Model, View, Controller model is at the core of Rails, and if you somehow managed to miss this in the first chapter of any Rails book, I’m shocked!  However, if you somehow did, you may hear it thrown around and get confused, especially if you come from another programming language and are still used to the old world “SQL and code inside your HTML file” world that you’ll be so happy to escape.
  • DRY – Another big one I’d be shocked if you didn’t know, it’s Don’t Repeat Yourself, another tenant of the Ruby and Rails world.  Basically this means that copy and paste programming is not a desired thing, and if you find yourself doing the same bit of code more than once (ie: formatting a price with a $ and decimal places) it’s best to find a way to move that into it’s own function so it’s only in one place.  This makes code easier to maintain, and keeps you happy.  Not a Rails specific philosophy, but definitely a core value.  Next time someone looks at your work and tells you it’s not DRY you’ll know what they mean.
  • Refactoring – Closely related to DRY, refactoring is the act of going back and seeing where you can extract common functionality or make the code more idiomatic or simple.  Different from Golf challenges in Perl by far.  Check out Refactor My Code if you want to get some great examples of how different people take the approach.  This site is awesome as you don’t just see the end result of good coding (as you’d see by reading (some) other people’s source code), but both the start and several alternative results.
  • Convention over ConfigurationThe idea that by following naming and file conventions, and following them, productivity goes up over a framework that allows you to configure where files are, how classes are named, etc.  By having a set of standard practices that you know your system follows, you can concentrate on what you’re doing and get sh$t done!  This is probably the most important tenant of Rails, and is pretty much what the entire thing is built on.
  • Framework – Going back a bit, what the heck is a framework.  Short answer is it’s something you build your applications in which provides you with everything you need.  In other words, instead of you having to deal with HTTP POST parameters for string processing, it provides you with libraries for data handling and common functionality.
  • CRUD – Speaking of things you don’t have to deal with, the biggest thing that I think web app developers have to deal with is the four common actions you’re taking with data (think editing a list of blog posts): Create, Retrieve, Update, and Delete.  This is shorthand for telling people that the data you’re dealing with has (or needs) the standard set of actions to edit, delete, show and create functionality.  This goes hand in hand with our last one…
  • Scaffolding – This is the concept of creating a default set of functionality that the programmer can update later on.  This is a quick and dirty way of getting things working, and is, in most cases, either only used for learning purposes or is rewritten later.  Creating a scaffold for a set of data (say a blog post) can be done in rails by running “script/generate scaffold Post title:string body:text”.  This will create a scaffolding which lets you have access to the CRUD operations on this new data model.  With just that one line above you get all the HTML, form processing, and database layer interaction needed to fully perform CRUD operations.  The concept of using scaffolding to create quick and easy access to data is a huge part of Rails’ success (even if you do end up rewriting them eventually, or grow out of using scaffolding as your skills improve).

There are lots more out there (this page has a great list).  Phusion, Heroku, nginx, nokogiri, sass, haml, copilot and scout are other terms for some specific software and sites and libraries you might come across.

Favorite Ruby and Rails Podcasts

Tuesday, April 27th, 2010

Podcasts have been a great help to get some great information about Ruby and Rails, as well as to discover and connect with more of the community.  I figured I’d list a few that I listen to, and would appreciate folks passing back any good ones I might be missing.

Some will be old hat to the ruby folks, but there might be some new ones that could peak pique your interest.  If you’re a newbie to Rails like me, I suggest you add these to your podcast watcher of choice immediately!  Most of these will fall into either the “news of the week”, “interviews”, “howto” or “training” categories.  I’ll categorize them for you a bit so you can pick and choose if you prefer one or the other.  There are a few that I’ve picked out that aren’t strictly Rails or Ruby oriented, but they still get prime location in my weekly podcast listening.

  • Coderpath [itunes] (audio,interviews) @milesforrest and @curtismchale
    Ok, so even though this is a bit of shameless not-quite-my-own self promotion, and Miles and Curtis are buddies of mine, I do have to honestly recommend the Coderpath podcast.  They do interviews of some of the big names in the Rails community such as DHH, Ryan Bates, Wayne Seguin and others, and ask a lot of good questions about some of the “how” of the community, the sort of questions someone like me might ask (and I do).  Also keep an eye on Miles’ twitter feed as he’ll send out where you can submit questions for the podcast.
  • RailsCasts [itunes] (video, training) @rbates
    Ryan Bates’ great podcast is a staple of the Rails community, and he gives short, bite sized chunks of information on different aspects of rails programming.  One week it might be how to do something like nested routes, another will be a series of Rails 3 howtos.  Awesome stuff.  Personally I’d recommend watching these and not deleting them, so you can go back for further reference later on.
  • Rails Coach Teach Me To Code Podcast [itunes] (audio, interviews, training and howto) @charlesmaxwood Note: Updated link, RailsCoach is now Teach Me To Code Podcast
    This is a recent discovery of mine, and Charles does a great job in intermixing interviews and talking about how to do various issues, such as finding a mentor or how to take the best advantage of your first (Rails|Ruby)Conf.  My favourite part of this podcast is that he seems to be (and no insult intended) about on my level, or a bit above, so a lot of the questions he asks would be pretty much exactly what I’d want to know in the same situation.
  • VimCasts [itunes] (video, training) @nelstrom
    Not purely a Ruby or Rails podcast, but vim is a skill that every programmer should know, and Drew does a great job in giving both a newbie friendly, and old-hat educating, series of screencasts.  If it says anything to you, I’ve been using vi and vim since around 1995 and was still learning things from the first podcast.  Great stuff in easy to digest chunks like RailsCasts.
  • RailsLab Scaling Rails [itunes] (video, training) @greggpollack
    This is a 21 part series that isn’t being updated anymore, but is a must-watch for anyone who wants to know a bit more about Scaling Rails.  This isn’t going to be applicable to 90% of what 90% of the audience does, but is still invaluable information in giving you the background information to know why certain decisions you make in technology can have big (or small) impacts on scaling down the road.
  • Your Workflow [itunes] (audio, interviews) @curtismchale
    Ok this is another bit of not-quite-my-own self promotion, as Curtis is a buddy of mine from the Fraser Valley Ruby Brigade (FV.rb).  This podcast addresses a niche that isn’t really addressed in other places, and takes that tack of “how do you get your job done” and talks about the workflow that people have.  Curtis is a designer and so far his interview has focused on wordpress development, but the site and podcast is all about people’s workflow, and you’re sure to find something new.
  • Ruby Pulse [itunes] (video, training) aaalex
    Ruby Pulse is to Ruby what RailsCasts is to Rails.  Alex takes a small chunk of code, a gem, or technology concept and works with it in a 5-10 minute podcast.  Ruby Pulse is unique is that it’s done in one go, with no editing, so as the intro says, sometimes unexpected things will happen.  More often than not, you’ll get a nice introduction to a new and interesting gem or two.
  • Ruby 5 [itunes] (audio, news) Envy Labs
    Ruby5 is the bite size chunk news show, and gives you the Ruby and Rails news of the week in a five minute podcast a couple of times a week.  Ruby5 was split off of Rails Envy for people who wanted their news a bit more compressed and less “chatty”.  Great way to hear what’s new and interesting and keep yourself right on the edge.
  • The Ruby Show [i], The Dev Show [i] and other good stuff from 5by5 (audio, news, interviews)
    Those familiar with Rails Envy will recognize these as cut from that tree.  5by5 has a very good series of podcasts with various names in the Rails and open source community, and has a great mix of news and interview shows.  The Ruby Show and the Dev Show are the ones that are on my podcast weekly, but I’ve also recently discovered The Pipeline, which is an interview show with innovators and newsmakers, and it deserves a listen as well.
  • Stack Overflow Podcast [itunes] (audio, news, howto and interviews) @spolsky and @jeffatwood
    Another not-really Rails oriented, but Joel Spolsky is a name that should be familiar to anyone doing development, as will StackOverflow.com.  You’ll also recognize Jeff Atwood from his great codinghorror.com site.  The guys get into some of the programming practices they follow, business, and interviewing people in their circle.  It’s a really interesting look into the development and business of the StackOverflow community.  Just ignore the whole “.NET” thing :)
  • The Changelog [itunes] (audio, interview) @adamstac and @pengwynn
    These are the guys behind tail.thechangelog.com and the github.com/explore pages, and give a great weekly interview with someone in the open source community, and really get into it from the philosophical point of view.  Being able to get a dose of what’s going on in the Open Source community is definitely an asset and their show (and the opening and closing music) is my Saturday must-have-on-while-driving podcast.
  • 37signals Podcast [itunes] (interview, howto) @dhh and @jasonfried
    If you ask for a Rails oriented podcast, how can you not include one from the company that started it all.  This one features DHH and Jason Fried sitting down and talking about all things community, rails and 37signals related.  Sometimes they are just chilling talking about Rails, sometimes it’s interviewing the sysadmin team, and somtimes it’s chatting about how the business side of the uhm, business works.  DHH is never one to hide his opinion about things, so it’s always a great and educational listen.

So there you go, hope you enjoy the list and find something new.  Remember though that you don’t want to get caught up in listening to podcasts about coding, and forget to do the coding yourself.  These will definitely give you a boost of inspiration, training, or just a weekly re-connection with the community.  Also please comment if I’ve missed any good ones!

Personal Projects For Learning

Tuesday, April 20th, 2010

One of the biggest struggles I’ve had is when learning something starts getting “stale”.  It’s a bit like a relationship, you go from the fun and new “getting to know you” stage and eventually plateau into the “how was your day dear?” “grunt” “that’s nice dear” stage.

I plateaued with Perl a while back I think, I definitely didn’t learn anything (I’m still picking things up from the Perl Best Practices book I have), but I found the set of functionality that works for me for 99% of what I need, and that I can manhandle into working for the remaining 1%.  It’s not a bad thing, but it’s not a good one either, because I don’t have the drive to new things with it.

I don’t think I’m at that stage with Ruby yet, but I was thinking today on the treadmill about how to avoid that and how to keep things fresh and interesting.  I figure that just like in photography, having a Personal Project is a great way to keep things fresh and interesting.  I came up with a few ideas.

  • A Code Sprint – They use the term “sprint” at my day job to mean a team that is concentrating on getting a new chunk of functionality or application out and done with minimul distraction.  I figure that I can do the same thing, set up a new idea for a site or project and work on nothing but that in my personal coding time (never at the day job of course).  This means when you’re done the initial fun stuff, database setup, object relationships, etc, you keep on going through the functionality, contact forms, logo, design, etc until it’s done.  It doesn’t have to be huge or take a month of your time to do, just make sure you don’t sit down and say “you know, adding feature XYZ… I’m not feeling it, maybe I’ll just catch up on Lost some more” (this is my personal battle right now!)
  • Learn a Class or Set of Functions Really, Really Well – Sure it’ll just be one class (Hash for example), or one set of functions (grep and array searching for example), and there’s probably no way to learn everything, but imagine the power to know that you have Hash under your belt, and that you know six ways till Sunday how to search arrays and similar objects, and the best practices and best idioms for it?  And that next week you can choose another class or set of functions to learn.
  • Answer X Questions A Day – The best way to learn I’ve found is to teach others.  Even if you just know a little bit you can probably bumble your way into some knowledge, and in that way you both learn.  Why not take on a question a day (or 5, or 10) on a forum like the StackOverflow ruby questions, or ruby reddit, or the ruby forums, and fully and completely, to the best of your ability, answer them.  Even if you spend the whole day researching and come up with the same answer that 10 other people have already given, you end up with a greater understanding, and you get to help other people.
  • Duplicate A Plugin – Sure you can just install Restful Authentication, or CanCan for Authorization, or activerecord symbolize, but why not learn what they are actually doing, and create that same core functionality “by hand”.  No need to do every nuance of what the plugins do, but creating an auth(entication|orization) system by hand is a great challenge so you know what’s going on under the hood next time you rely on just running “script/plugin install….”

Those are some good suggestions, what do you other ruby and rails hackers do to learn more or keep yourself sharp?

Better Way To Do Dynamic Methods

Tuesday, April 13th, 2010

Not sure how best to describe this, so I figure a few lines of code can say a hundred words at least:

# app/models/user.rb
  # This lets me call @user.home_page from within views or controllers to create a URL
  def home_page
    if self.referee?
      return "/bids" # sends user to site.com/bids
    end
    if self.assignor?
      return "/assignors" # sends user to site.com/assignors
    end
    # [... etc ...]
  end
 
  # dynamically determine the role name as a method
  # can this be done to to_sym or something better,
  # or a missing_method call to make it dynamic?
  def referee?
    if self.role.name.downcase == "referee"
      return true
    end
    false
  end
 
  def assignor?
    if self.role.name.downcase == "assignor"
      return true
    end
    false
  end

What I really want to do is call “bids_path” or “assignors_path”, but those don’t seem to be available from within the model file. I’m sure there must be a better way to do this, from two different aspects:

  • The first part of the code, returning the actual path, or at least the dynamic resource path instead of having it hard coded. This is possible in the view, but I’d have to fill it up with checks for the user type and then calling either bids_path for referees or assignors_path for assignors
  • The second part, where I create the two methods to make the above determination. I could just trust that the @user.role.name will return The Right Thing, but I’m not sure how to auto-magically create the methods to do this for anything that the user.role.name contains.