Archive for Development

Cloudy, with a chance of open source

In our quest to be completely buzzword-compliant, we’ve implemented Backboard and embedit.in as “cloud computing” applications; that is, the servers on which they run are virtual private server instances. It’s great: we can add as much capacity as we need without having to acquire and set up hardwarea and scale to traffic dynamically.

One piece of software without which this would be much less enjoyable is the RightScale libraries, released as open source by RightScale. They’re great, wrapping all of the Amazon Web Services APIs — and Amazon’s competitors’ APIs, too — in a straightforward, well-documented Ruby library. It’s interesting that RightScale is doing this open source play, since their bread and butter is creating deployment solutions and magic scaling sprinkles for cloud-hosted applications. But their libraries are solid and comprehensive, to boot.

Installing them is:

sudo gem install right_aws

after which you can use them from IRB or from Capistrano or from your application. No downloading one set of Java command-line tools for EC2 and a a Firefox extension for S3. No configuring environment variables and setting up a Java Runtime Environment. Easy!

One caveat to point out if you’re using JRuby: the jruby-openssl library doesn’t support SHA-256 for generating HMAC signatures, but it does support generating SHA-256 digests. This defeats the mechanism in right_aws for figuring out how to sign Amazon Web Services requests. To work around and force SHA-1 for request signatures, this monkey patch works:

# Icky, icky monkeypatch.
module RightAws
  def AwsUtils.blow_away_sha256
    class_variable_set '@@digest256', nil
  end
end

# Called later:
RightAws::AwsUtils.blow_away_sha256

We love the RightScale libraries for their completeness, allowing us to avoid learning a new library for every place we might want to do something with cloud computing or web services.

Comments

The motivation of a good schedule

It all started with Jeff’s tweet from a week and a half ago:

Never be too cautious with estimates - it fails to motivate you. What we spec'd yesterday as 1 week of work, I just did in 1.5 hrs.

It got me thinking: what, then, does motivate us? My initial reaction was to disagree: nothing is a bigger de-motivator than a project schedule that’s unrealistically short. As soon as I got over my sense of smug satisfaction from having a decent counter-argument, though, I understood what I believe to be Jeff’s real point. I think it comes across better as the converse:

Never miss an opportunity to make something happen quickly and successfully — it will leave you feeling motivated like nothing else can.

Read the rest of this entry »

Comments (1)

Is OpenID the future?

Yesterday, I was reading a thread on evolt.org’s thelist, perhaps the oldest community of web designers and programmers around.

The topic of the thread was OpenID, the implementation of which on websites is one of the most contentious issues I’ve seen in a long time. Some of the input from the thread:

I have discovered OpenID,
Here is a link if you haven’t heard of it, http://openid.net/
I am un-sure at the moment whether this is a good secure service and I was wondering if any of you folks had any experience with this.

Last I checked, it was going to be too much of a headache for us to implement

I’ve only seen it used on stackoverflow.com, which is even a headache
for a user if you don’t habitually authenticate with one of their
OpenID providers whenever you surf.

I gazed over the specs and that’s exactly what happens.

Personally, I wouldn’t even bother with it. I think it’s a case of “good
ideal, bad implementation”.

Given that Backboard allows you to authenticate with OpenID:

Backboard OpenID log in

and that embedit.in requires you to do so (the buttons for AOL, Yahoo!, and Google are merely shortcuts to the OpenID URLs for those providers):

embedit.in OpenID log in

you might suspect we have something to say about the whole matter. And you’d be right. The way we see it, OpenID fundamentally solves two very important problems while creating one new problem.

Read the rest of this entry »

Comments (2)

Pimp my JavaScript, part 2: The biggest gotcha

Every language has its gotchas.

In Ruby, for example, zero and the empty string both evaluate to true in a boolean context. In PHP, several of the built-in functions aren’t functions at all but are really just language features disguised as functions. In Perl, the local statement doesn’t make local variables, but the my statement does. In Objective-C, you can send messages to nil and nothing happens.

Of course, those other languages are a whole different blog post: today’s topic is JavaScript, and what may be its most subtle gotcha.

Consider the following two relatively similar functions. The first is in JavaScript:

function alertLater() {
    var local;
    for (local = 1; local < 6; local++) {
        setTimeout(function () {
            console.log(local);
        }, local * 1000);
    }
}

The second is in Ruby:

def alertLater
  threads = []
  (1..5).each do |local|
    threads << Thread.new do
      sleep local
      puts local
    end
  end
  threads.each { |thread| thread.join }
end

What is the output from each?

Read the rest of this entry »

Comments off

Text highlighting and speed improvements

Last week brought some big changes to Backboard.  A few things that we wanted to push didn’t quite make it into that release, so yesterday, we updated Backboard yet again with some nifty new features.  Upload a new Backboard and check them out!

Text highlighting

Ever find yourself wanting to highlight the text in a Backboard instead of underline or circle it?  Well now you can.  Simply mouse over the text in question and highlight away.  You’ll still get the familiar text entry box to make your suggestions, but now the selected area behind the text will remain highlighted.

Text highlighting example.

The need for speed

If you have a lot of Backboards on your My Backboards page like we do, then you probably noticed that the page took some time to load.  Well wait no longer, we’ve significantly improved the loading speed of the My Backboards page.  Images are only loaded when you need them and no earlier, meaning the page loads and responds much quicker.  We also made some tweaks to the javascript loading on other parts of the site to improve response times and will continue to look for places we can improve the speed of the site.

As always…

We love bringing you new features and we hope you’re as excited about these changes as we are.  As always, let us know what you think!

Comments off

The easiest tech demo, ever

I gave a short three-minute presentation to the Silicon Valley JavaScript Meetup Group last month about Backboard. I talked a little bit about Backboard and how it does real-time feedback using Orbited. Enjoy!

Comments off

Pimp my JavaScript

As the Backboard experience gets richer and richer, more of it moves to the browser from the server. It’s a win-win-win: Increo gets less load on our servers, you get better response time on your computer, and the team gets to write code in the awesome language that is JavaScript.

As such, we’ve spent a long time working on making it as consistent and manageable as possible. With apologies to Wil Shipley, some basic suggestions for maximum JavaScript happiness follow.

Use a JavaScript framework

If you’re still writing JavaScript without relying on one of the myriad open-source DOM-savvy Ajax frameworks, you’re wasting your time and effort. You have lots of choices:

Backboard is built on the (large and supple) shoulders of Prototype, but we hear they’re all pretty good.

Don’t host your own copy, though: use Google’s hosted version. That way, your whole app loads faster when your users don’t have to even download the JavaScript file because it’s already in their caches.

Use namespaces, or the next best thing

Sure, JavaScript is technically a language with a flat namespace, but since it’s prototype-based instead of class-based, you can just use objects. Instead of this:

function my_namespacer_hopefully_nobody_collides_runRequest(arg1, arg2) {
    return "Haha! This function has a really long name!";
}

you can have a simple “namespace” object of your own:

var MyStuff = MyStuff ? MyStuff : {
    runRequest: function (arg1, arg2) {
        return "So much better!";
    }
}

You may think you’re organized enough to keep everything straight, but once you start pulling in libraries and other people’s code, you’re going to be in a world of hurt. After all, you don’t want your next big app looking like PHP.

Employ some automated syntax checking

And by “some automated syntax checking”, I mean JSLint. We use the following set of options for our source code:

JSLint options

The face of Backboard (that is, the JavaScript that runs in the browser) is almost 1,300 lines of JavaScript. Running it through JSLint helps prevent dumb errors and bugs and it keeps all of us honest. Having an easy way to enforce coding guidelines makes it easier for everybody to work together and make your quality consistent.

Let your server deal with download efficiency

Shipley sez “Tiny code is always best”, but I’m pretty sure what he means is you should express yourself briefly, without wasting code writing extra methods you don’t need or class hierarchies just because you can.

Repeat after me: whitespace is okay. So are comments.

You’re better off writing beautiful, well-documented, understandable code and having your application compress it with things like JSMin or the YUI Compressor and mod_deflate.

Those 1,300 lines of JavaScript in Backboard started at 46 kilobytes; after running them through JSMin and mod_deflate, they’re 8.2 kilobytes. Having it set up to run automatically is an order of magnitude more worthwhile than any effort to minimize code size.

All of this leads us ever closer to JavaScript happiness. And, of course, that’s the whole goal, right?

Comments off

Flash embedding: an object lesson in simplicity

When we launched embedit.in last month, the focus was on simplicity. No registration required, no seven-step process, nothing. Just upload a file and click “Embed It!”

Of course, the back end isn’t quite so simplistic: it stores your file, converts it to be viewable in our player, and generates the code for you to embed on your site. That last step presented us with an interesting challenge.

The initial version of the code used the OBJECT tag, complying with HTML standards. It was short, it was simple, and… it didn’t work in Internet Explorer 7.

<object width="466" height="400"
    type="application/x-shockwave-flash"
    data="(url of flash file)">
    <param name="allowFullScreen" value="true" />
</object>

Much has been written about the best way to embed Flash in webpages, and the state of the art is that the EMBED tag is bad, and the OBJECT tag is good, but requires different sets of attributes based on what browser is viewing the page.

That leaves us, therefore, with a need to have different markup depending on the browser, so libraries like SWFObject were born. Every browser gets the correct markup using the OBJECT tag, the HTML standard doesn’t feel violated, and another angel gets its wings.

One problem: it relies on JavaScript being available in the browser and a library being loaded. For an app like Backboard, that’s totally reasonable, but when the entire point is to let people copy a single line of code in to their site, it doesn’t work. So where does that leave us? That’s right, partying like it’s 1999.

<embed width="466" height="400"
    type="application/x-shockwave-flash"
    src="(url of flash file)"
    allowFullScreen="true" />

Hey, look! It works in every browser, it’s just as functional, and the code is even shorter than before. Maybe it’s not standards-compliant, but it’s reliable, and isn’t that the point of standards in the first place?

Comments off

The IE 6 Blues

Well it’s the most wonderful time of the year again, and I’ve been listening to a lot of holiday music. An album I’d definitely recommend is Christmas with the Rat Pack – it’s got a bunch of classics and I’ve been listening to it almost everyday while I code.

Recently at Increo we’ve made some major updates to Backboard, including a new viewing experience and the ability to organize Backboards into projects. Developing those two features was fun and challenging — they’re excellent examples of why we love making great software. However, one aspect of development I dread is making sure Backboard works in all the major browsers. Backboard officially supports Internet Explorer 6 or later, Safari 2 or later, and Firefox 2 or later. Most of the browser rendering discrepancies are minor, except for those pertaining to IE6. So to express my frustration, I’ve written a little poem/song in the holiday spirit:

The IE 6 Blues (sung to the tune of The Christmas Blues by Dean Martin)

We’re making applications
For the triple-W,
But there come some big frustrations
When I need to look into

How our code is generated
In IE 6’s shoes.
It’s giving me the IE 6 blues.

Read the rest of this entry »

Comments (1)

Adventures in ad-hoc networking

Warning! Technical content ahead!

Increo’s office network is small and simple. All of our servers live at professionally-managed data centers, and our office has nothing more than a consumer-level wireless router on a shared Internet connection from Palo Alto’s Fiber Internet Center. Everything is wireless. It’s great, inasmuch as our total network equipment cost was in the two digits and adding a new computer takes no time at all. There’s no DNS server and no IP assignment; everything “just works”.

It becomes interesting, of course, when computers in the office need to connect to each other. For this, we turn to Zeroconf and multicast DNS, implemented as Bonjour on the Mac, Bonjour for Windows on Windows, and the team of Avahi and nss-mdns on Linux.

Now we can use computer names to connect to each other’s machines, no setup required. It’s really slick, and it has worked really well for us. At least, it works seamlessly up and to a point.

Read the rest of this entry »

Comments off