will.thoughts.pop
RSS icon Email icon Home icon
  • Flushing memcached servers from Ruby

    Posted on January 8th, 2010 Will No comments

    In Flushing memcached servers the easy way I highlighted a way to flush a memcached server without restarting it:

    $ echo ”flush_all” | nc localhost 11211

    However I almost never use the actual shell version of this, mostly I do the equivalent in Ruby by opening up a socket and communicating through that. Here’s a simple example:

    socket = TCPSocket.new( '127.0.0.1', 11211 )
    socket.write( "flush_all\r\n" )
    result = socket.recv(2)
    puts "Success!" if result == 'OK'
    socket.close

  • Optimising the Recycling Group Finder – Making a Ruby on Rails app faster

    Posted on October 17th, 2009 Will No comments

    This is really just the ’story’ of how I fixed a very slight performance issue with the Recycling Group Finder site that I run, but I figured it would be worth a post as an example or motivation to anyone else who needs to get started investigating their own Ruby on Rails app performance issues.

    The performance problem

    I’ve been very happy with the responsiveness of the Recycling Group Finder, so just out of interest, just to see what it would tell me, I installed the NewRelic RPM plugin and activated the free Bronze account available to EngineYard customers. The results were pretty satisfying as my average response time for the most popular page was 163ms maximum with the second most popular page at 90ms. Those are good response times and fall well within the 37signals response time rule:

    Our general rule of thumb is that most pages should render their HTML on the server in less than 200ms and almost all in less than 500ms.

    Suspicious looking

    One of the great things about data visualisations is it can make it really easy to spot patterns. Take this New Relic graph for example:

    Recycling Group Finder - graph, before optimisation

    Recycling Group Finder - before optimisation

    The yellow on the graph represents time spent in the database, the blue is time spent in Ruby, ie. rendering, controllers etc. Memcached accesses are on there too but they’re so fast they hardly appear. This graph looked suspicious to me, I’d normally expect database time to be a much smaller proportion of the overall request time. So it looks like there may be some optimisation that can be done, but in order to optimise I first need to know what to optimise.

    The hunt

    Google for “rules of optimisation“. Most rules are something like this:

    1. Don’t optimise yet
    2. If you need to optimise, profile first.

    I’m never going to be able to optimise my code unless I know what to optimise. If I trawl through looking for places that might be slow and trying to make them faster the chances are I’m going to spend hours changing code for no benefit. I might even make it slower. I need to know exactly where the bottleneck is, I need to profile my code.

    There are a bunch of ways of finding out where your code is slow and I’ve personally used ruby-prof before with good results. However I know that the issue here is in the database, and I know that Rack::Bug will show me SQL queries that have run for an action, and importantly how long they took, so that’s what I’m going to try first. I install the plugin, configure it and load it up. The issue is immediately obvious:

    Recycling Group Finder - Rack::Bug SQL queries

    Recycling Group Finder - Rack::Bug SQL queries

    Almost all of the SQL that is executed is under 0.5ms per query, there are a few queries at ~4ms but he one query that really stands out is the third one down. At 44.75ms it is more than half of the overall SQL time. Bingo! Now I know what is slow I need to know why it is slow. Time to break out the query analyser.

    Fixing it

    I needed to dig deeper into that SQL statement to see what it was doing, so I opened up a postgres shell and ran an explain analyse on the query:

    The issue seems pretty clear. There is a Sequential scan on groups:

    Seq Scan on groups (cost=0.00..626.75 rows=4885 width=363) (actual time=0.038..26.495 rows=5126 loops=1)

    A Sequential scan on a large table is going to sink performance. I can see that the sequential scan is definitely the issue in this case as the cost and time taken are significant proportions of the overall query time. I need to eliminate it. Here’s the code that generates that query:

    @groups = Group.find(:all, :include => :group_page, :origin => [@location.lat, @location.lng], :limit => 30, :conditions => ["defunct = false AND lat is not null and lng is not null and full_address is not null and full_address != '' and country_code = ?", @location.country_code], :order => 'distance ASC, num_members DESC')

    I wrote this code ages ago and re-reading it now I can see that although I am limiting the returned results to 30 rows the query will have to hit every row in the table to determine which rows are in the returned 30 as there are no conditions to the query. Whoops. Looking over the Geokit docs I see there’s a :within condition so I added a :within => 100 to the find. Testing the resultant query in the postgres shell using explain analyse again and the query has dropped to 10ms. Not bad but it’s still using a sequential scan. Adding an index on the conditions speeds up the query further to ~1.2ms:

    Not bad when it started out at nearly 45ms. Here is the result reflected in the New Relic graph:

    Recycling Group Finder - After optimisation

    Recycling Group Finder - after optimisation

    I deployed the new code approximately in the middle of the graph, it should be pretty obvious where.

    Conclusion

    Before you can optimise your Ruby on Rails app (or your app in any other framework/language for that matter) you need to know know where to optimise. Tools like Rack::Bug and NewRelic allow you to do this effectively and easily allowing you to direct your attention only on those parts of your app that need the attention.

    On the Recycling Group Finder I cut response times drastically in about half an hour. Without knowing exactly where to make the change I would have been left guessing and may never have made the optimisation I did.

  • Looking for a Web-Development job? Learn Ruby and Ruby on Rails

    Posted on October 12th, 2009 Will 5 comments

    Seriously. Not only will you be able to develop web-applications faster and with more joy, but if you fill some of the many Ruby on Rails job vacancies there are going the recruiters might stop bugging me so often.

    There are Ruby on Rails jobs out there

    Or that’s what is seems like from talking to people at the NWRUG and Geekup meetings I go to and by the phone calls I get from recruitment agents. I know of companies worried about using Ruby and Rails because of concerns over the number of developers available. These companies need you and they need you to write web applications for them in Ruby on Rails! These are companies who want to use Ruby on Rails and they will hire you if you learn it.

    I’m fine sticking with $some_other_language but thanks anyway

    That’s fine, there are lots of jobs available using your programming language. Well, maybe not if that language is Coldfusion. But if you expand your horizons, teach yourself something new and can prove to others that you’re interested in and capable of learning then you’re going to be a more valuable asset. That’s going to translate into more pay and a more fulfilling job using a language as expressive as Ruby and a framework as labor-saving as Ruby on Rails.

    Worst case scenario is that you learn Ruby on Rails and you can write your own web-apps a whole lot faster (you do write your own web-apps right?), your CV looks better and you have more time for the dull stuff that you fit around programming. Watching Buffy or something. You know, programmer social life stuff.

    I tried Ruby and Ruby on Rails already but I prefer Python…

    Weirdo.

    I tried Ruby and Ruby on Rails already but I prefer Cobol!

    You don’t exist, go away.

    You were thoroughly convincing, I’m sold

    This post is so convincing that when I proof read it I nearly went and learned ruby on Rails myself, even though I already know it. If you want to you learn you can start here, and there’s going to be a local Ruby user in your area somewhere, sign up to their mailing list, we’re a pretty helpful bunch.

    If you’re anywhere near Manchester, UK then come along to the next NWRUG meeting, it’s this Thursday and there’s free pizza. You need to sign up to attend.

  • Nothing left to take away

    Posted on August 7th, 2009 Will No comments

    Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.
    — Antoine de Saint-Exupéry

    Coding often feels like this.

  • Whiny git – getting rid of the ‘You did not specify any refspecs’ error

    Posted on July 19th, 2009 Will 5 comments

    Newer versions of git will complain if you just do a

    git push

    in your current branch to push it to a remote:

    pleb:funpop will$ git push
    warning: You did not specify any refspecs to push, and the current remote
    warning: has not configured any push refspecs. The default action in this
    warning: case is to push all matching refspecs, that is, all branches
    warning: that exist both locally and remotely will be updated. This may
    warning: not necessarily be what you want to happen.
    warning:
    warning: You can specify what action you want to take in this case, and
    warning: avoid seeing this message again, by configuring 'push.default' to:
    warning: 'nothing' : Do not push anything
    warning: 'matching' : Push all matching branches (default)
    warning: 'tracking' : Push the current branch to whatever it is tracking
    warning: 'current' : Push the current branch
    Counting objects: 37, done.
    Delta compression using up to 2 threads.
    Compressing objects: 100% (20/20), done.
    Writing objects: 100% (21/21), 4.58 KiB, done.
    Total 21 (delta 11), reused 0 (delta 0)
    To git@github.com:wjessop/Funpop.git
    e9ca06a..5507c19 master -> master

    You can get rid of this by just doing:

    git config --add push.default current

    and now git will work like it did before, without the noise.

  • NWRUG Code Surgery and an introduction to Zsh – Tonight

    Posted on June 18th, 2009 Will No comments

    the June NWRUG is tonight. There will be a code surgery and introduction to Zsh. Plus free pizza!

    Email me or leave a comment to sign up.

  • Blocking Internet Explorer 5.5

    Posted on June 15th, 2009 Will 2 comments

    IE 5.5 is dead. The number of people using it are tiny, at least according to the stats on the most popular sites I run. Here are the numbers.

    Jokes-o-matic

    Has a larger proportion of Firefox users than Internet Explorer users due to the high level of traffic from some social bookmarking sites, meaning a more web-savvy crowd who are more likely to be using alternative browsers:

    jokes-o-matic.com browser breakdown

    jokes-o-matic.com browser breakdown

    The level of IE usage is still pretty high though, but even so only a single hit from IE 5.5 recently:

    jokes-o-matic.com IE versions

    jokes-o-matic.com IE versions

    Recycling Group Finder

    A much more broad and ‘average’ user base with Internet Explorer dominant:

    Recycling Group Finder browser breakdown

    Recycling Group Finder browser breakdown

    Still, only 6 Internet Explorer hits recently, a tiny proportion of overall visits:

    Recycling Group Finder IE versions

    Recycling Group Finder IE versions

    What does this mean?

    Yahoo.com as seen in Internet Explorer 5.5

    Yahoo.com as seen in Internet Explorer 5.5

    These statistics, and others I have seen suggest that almost no-one uses Internet Explorer 5.5 or below any more. The small minority that do must be used to the internet breaking in unique and interesting ways due to the lack of support for more recent developments in CSS and really bad Javascript support (see right for yahoo.com as seen in Internet Explorer 5.5). I predict that a fair number of sites just don’t work in any usable way on anything less than Internet Explorer 6.

    Time is money

    Designing for multiple browsers takes time. The more browsers you need to support the more time you need to spend supporting them.

    A recent project I worked on required a redesign of the site from the ground-up (aswell as a bunch of other stuff) and making the site work in any version of Internet Explorer lower than 6 just wasn’t worth the time, and therefore money, put into it. The return just wasn’t there and I decided that IE 5.5 was gone, dead, obsolete and I wasn’t going to try and mangle the design to work in it. Rather than just display a really crappy looking site to the user I decided I would let them know via a short and to-the-point message that their browser was not up to displaying the site and directing them to upgrade to a new version of their browser.

    Give them the good news

    IE 5.5 advice message

    Message displayed to all users visiting project in anything below IE 6

    But how to do this? The site was developed in Ruby on Rails and I’d heard of a neat gem called rack-noie6 that provides a piece of Rack middleware that blocks Internet Explorer 6 and below, but that isn’t going to work in most cases. Hard as it may be to make your site look good in Internet Explorer 6 you can see from the stats above there’s still a large proportion of users using it and to turn them away would be crazy, at least while the pool of IE 6 users out there is still so large.

    So a quick fork and patch later (github we <3 you so much) and the new noie6 was accepting an option for a minimum version of Internet Explorer it should accept instead of just rigidly blocking version 6 and below. Configuration is really simple:

    Now any users visiting the site in anything below Internet Explorer 6 gets the message above helpfully directing them to update their browser. Not bad for a two line config update.

  • NWRUG 19th March – Search in your Rails app – writeup

    Posted on April 7th, 2009 Will No comments

    The March meeting went really well, nearly 20 people turned up and much pizza was consumed. People seemed to enjoy the talks and the new BBC venue was great too, so success all round!

    I have the slides up from my talk on sphinx and John has the slides from his Ferret talk up too. I will put Asa’s slides up when he sends sends me them/a link!

    Next meeting

    The next meeting is on the on the 16th April and is titled “BDD, you know you should be doing it”:

    So, you’re testing your code right? Of course you are! But are you testing your code as well as it can be tested? This month Ashley Moran, Testing Maven, will be giving a talk and practical session on Behavior Driven Development and how it should be done right.

    Hope to see you there!

  • Next NWRUG meeting – 16th April – BDD, you know you should be doing it

    Posted on April 7th, 2009 Will No comments

    So, you’re testing your code right? Of course you are! But are you testing your code as well as it can be tested? This month Ashley Moran, Testing Maven, will be giving a talk and practical session on Behavior Driven Development and how it should be done right.

    We’re starting 30 minutes earlier this month due to the practical nature of the session.

    This month we have sponsorship from Engine Yard so there will be free Pizza (and maybe Beer and soft drinks, depending on the numbers) during the talks.

    Schedule

    • 6:00pm :: Welcome & Pre-session bar visit
    • 6:30pm :: BDD, why you should be doing it and how. Pizzas provided by Engine Yard will be served during the session
    • 8:30pm :: Drinks at the BBC bar afterwards, then somewhere else nearby after that closes at about 21:00.

    If you want more information email nwrug at willj.net or call Will on 07939 547 962

    Sign Up

    If you would like to attend this event please email me (nwrug at willj.net) as the BBC need a list of attendees before the event and I really need to know the numbers so I can order the right amount of food and drink. This month I shall be publicly coating people with blancmange who turn up without emailing me. You have been warned.

    Location

    This meeting is being held at one of our regular venues, the BBC Manchester main building on Oxford Road in central Manchester. If you get lost call Will on 07939 547 962.

    You can find the exact same information on the NWRUG site in a more bookmark-able form.

  • NWRUG February 2009 – Nanite talk

    Posted on February 20th, 2009 Will 3 comments

    For the first time in quite a while we had a talk at NWRUG, it seemed to go well and the free Pizzas and Beer provided by Engine Yard were very popular. About 12 people turned up. I was the only speaker and did a 45 minute talk on Nanite with a brief introduction to cloud-computing as that’s the environment I see Nanite being most useful.

    Thanks to everyone who turned up and Engine Yard for the sponsorship. I promised a blog post with links to some of the resources from the talk, and here it is!

    Useful links from the talk

    Nanite (of course)

    Kestrel (a starling replacement)

    Delayed Job

    Warren (A wrapper around AMQP from brightbox)

    Engine Yard Solo

    As I mentioned in the talk you can probably get away with using third-party APIs and calling it ‘cloud-computing’, this set of slides is really interesting:

    Web Hooks and the Programmable World of Tomorrow

    Lastly the slides on SlideShare, though they don’t make as much sense as they do with the talk & my notes.

    *update*

    Pastie: control rabbitMQ using Nanite, controlling god using Nanite.

    Next Month

    More talks! Asa Calow has agreed to do a talk on Solr and I rather foolishley agreed to do another talk on Sphinx.