Archive for the 'Programming' Category

23
Jul

Lazy Testing your URLs

So I have a Rails app that’s broad but not very deep: there are a lot of different types of URLs and thousands of pages, generated dynamically or built through a CMS. No one page is that complicated, but there’s a fair amount of shared code and thus some tentacles throughout. Yes, I should have written behavior-level and unit-level tests from the beginning, but I didn’t, don’t judge me.

Anyway, after I broke the site yet again, I realized what I really wanted was a post-release test suite – I wanted to test a whole bunch of pages in production and make sure they’re still rendering.

Stealing from the Net::HTTP canonical examples, then, I wrote a standalone script:

require ‘net/http’

URIs = [‘http://example.com/’, ‘http://example.com/page/2’]

puts “Running URL Test Suite…”
URIs.each do |uri|
  url = URI.parse(uri)
  req = Net::HTTP::Get.new(url.path)
  res = Net::HTTP.start(url.host, url.port) { |http| http.request(req) }
  unless res.code == ‘200’
    puts “ERROR: #{uri} #{res.code}”
  end
end
puts “Test Suite Complete!”

Then, since I deploy directly with git, I added a call to this script in my post-receive hook. As long as I watch the deployment (which I do anyway), I’ll see if there’s a problem and fix it immediately. (I can handle a few minutes of downtime or just roll back.)

There are obvious improvements to this (like not storing the URLs in the file), and this doesn’t handle redirect, workflow, or authentication scenarios, but it’s a perfectly acceptable 99% case for a content site.

Note that if you are doing Rails development and you’ve built a custom 404 page, you’ll want to make sure that you’re actually returning a 404 status code, or this won’t catch errors: you can test your status codes, and if you aren’t, you can add code in your application controller to do the right thing.

30
Sep

Programming: write it down (again)

Last day of last month, I talked about the importance of writing down your questions when you’re programming. Last day of this month, similar post – now, it’s about writing down your algorithms when you’re programming.

Since college (when I would “program” by the light of a desk lamp at the top of a bunk bed – pre-laptop), whenever I have a reasonably complex piece of logic to work through, I always start with a piece of paper and pencil, and I sketch out the entire algorithm in pseudo-pseudocode – basic structures, algorithms, control flow. (It’s like being at the board for an interview, but nobody’s watching.)

Why do this? In order of importance:

  • You can focus on the problem. When you’re writing real code, you’re focusing on a lot of things – the logic, but also the syntax and markup, the object-method structures, the tabs, the comments, the format. Each of those things takes some thought, and each moment causes a mental task switch from solving the real problem. (Maybe you’re both so talented and so experienced in a particular language and IDE that none of those things actually require any thought – you’re as fluent as you are in your native tongue. But I’m not, and you’re probably not either.)
  • It’s much faster. You might type faster than you write when taking notes, but nothing’s faster than writing fake code on a piece of paper, drawing arrows and braces to mark sections, using carets to insert content, etc. You aren’t worrying about any of the things above: you will find the problems in your thinking much, much more quickly.
  • You can do it anywhere. On the bus, by the bed lamp, when you’re pretending to make art with your three-year-old. You can think about the algorithm in between things and record your notes, rather than waiting for the moment you’re sitting down. Paper & pen are still more accessible and portable than the MacBook Pro.

Highly recommended approach. Let me know if this or similar things work for you!

26
Sep

Vaporbase micro-CMS: Performance Improvement

(Warning: code talk ahead.)

When I started building the app I’m working on, I needed a quick CMS system that didn’t impose its own parsing language, and I was just learning RoR, so I implemented the Vaporbase micro-CMS based on this great tutorial. While you wouldn’t confuse this with a pro-grade CMS system, it works just fine for the most part, and doesn’t require you to learn a number of new things.

Since implementing it, I’d made a few minor cleanups, but nothing significant, until I had 60 pages in the CMS, and saw a problem: the list of pages was taking a very long time to load (21sec on avg on my dev machine).

Sure enough, there’s a problem: in the Edit and Show Tree Hierarchy section, here’s a line that says

<% unless index_item.children.nil? %>

Looks innocuous, right? Not exactly: for every single page in the tree, this does a separate SQL query (which is a full table scan, though likely on a tiny table) to find out if that item has any children. So creating the page is O(# pages in table), and while the queries itself aren’t that expensive, building the page just takes a while. If your tree is mostly flat – almost certainly the case for this kind of CMS – you’re wasting a lot of time.

Fortunately, there’s an easy solution: when you get the list of pages before creating the tree, figure out which pages have children, and then store that list to the side. It adds a bit of code, but not a lot.

# Original: from the index action in the controller
# This gets just the root nodes and then recurs down the tree
@pages = Page.find( :all, :conditions => [‘parent_id IS NULL’], :order => :position)
# Replacement:
# build two arrays –
# @pages consists of all of the root nodes (since the view walks down the tree)
# @pageIDs_with_children consists of all pageIDs which are the parent for >=1 page

@pages = []
@pageIDs_with_children = []

@all_pages = Page.find(:all)
@all_pages.each do |page|
if (page.parent_id.nil?)
@pages << page else @pageIDs_with_children << page.parent_id end

(Note that the list might have duplicates, but that doesn’t matter. If that makes you unhappy, check for existence in the else clause.)
Then replace the view line above with

<% if @pageIDs_with_children.index(index_item.id) %>

I saw a >80X performance improvement on this page with this change in development (from >20sec to ~0.25sec with 60 pages), and you’ve just replaced an expensive linear scaling step with a very inexpensive one.

22
Sep

Search Evernote, not Google

I’ve played with 100 note-taking/history-recording tools over the years, and none of them have ever really taken off for me. I started playing with Evernote soon after the beta began, and while I loved the interface and the story, my uses were very occasional.

Now, however, I’m constantly in Evernote – it’s third only to my browser and Textmate – as I’m coding. 

Why? I’m using it as a programming information repository. Every day that I program in Ruby on Rails, I learn a few new things or change the way I do things – today, for example, I learned that interpolation is faster than concatenation, and yesterday I finally found a clear explanation on how yields work. What I do now is every time I find an interesting piece of information, I clip the whole page to Evernote, add a few tags, and then keep on going. Occasionally I’ll paste screenshots from the PDFs of some books I own as well, which then (usually) get magically transcribed for me.

I’ve realized that I was using Google to search for the same information over and over again, and then trying to remember which link I liked the best. With Evernote, I’ve already recorded that memory, so I just have one source. Every day a greater percentage of my programming-related searching is happening in Evernote.

I’ve thought about making a separate notebook for my Rails/Ruby content and making it public – if I do so, I’ll post it here – though obviously it’s not a replacement for an actual text, it just has pointers to things I’ve cared about. However, if a dozen people did this, I’d love to have links to all of their notebooks.

31
Aug

Programming: When you’re stuck, write it down

Hey. Long time, no blog. Been busy.

Thought I’d share a tip that I’ve used for many years when programming (or learning almost any new thing) and I’ve been using recently: when you’re stuck, write it down.

Say you’re trying to figure out how to do something in [pick a framework], and you’ve Googled the heck out of the most-likely search terms, and nothing’s coming up.

Then write down your question as if you were going to ask a teacher/email it to a friend/post to a Google group/etc. Write down all the details: explain the thing you’re trying to do, the problem you have, and the number of things you’ve tried. Be as clear as you can, but don’t worry about being concise.

Literally every single time I’ve ever done this – and my rule-of-thumb is to do it after ~1.5 days worth of trying to figure it out myself – I find a number of new avenues to try, and almost always solve the problem on my own.

Writing it down forces you to take the jumbled thoughts in your head (they probably weren’t jumbled when you started, but you’ve changed paths so many times now) and turn them into a narrative. The process makes visible paths that your random walk opened up but that you didn’t see.

(This has been a procrastination for completing a writeup of my own.)




Twitter Updates

[aktt_tweets count="5"]