Archive for the 'rant' Category


The LAMP Stack is Dead. Long Live the LAMP Stack!

Recently Mike Driscoll took a shot across the bow of the LAMP stack in an article called Node.js and the JavaScript Age. Arguing that the LAMP age (2000 to 2009) was about shuttling data back and forth from the database, he asserts that in the JavaScript age

The principal role of the server is to ship an application to the client (Javascript), along with data (JSON), and let the client weave those into a DOM.

Mr. Driscoll envisions a world where the server becomes “dumb” and the client increasingly becomes the brains of the operation. This comes after his team migrated a dashboard application from Django (Python) into node.js (JavaScript). Mr. Driscoll points are compelling. Imagine that after more than a decade of technology specialization we may finally be on the cusp of a fully unified web stack – mongodb as your data store, node.js as your server environment, and JQuery in the browser – based entirely on JavaScript. We could be witnessing the dawn of the JavaScript stack.

The benefits of the JavaScript stack are clear – code libraries shared across a homogenous team of JavaScript developers leading to reduced development and maintenance costs. All of your unit tests in one language! How can it fail?

In reality it’s probably not going to be that simple.

One big hole (pun intended) in Mr. Driscoll’s design is security. Yes, in some applications only 10% of your server-side templates are HTML. But that 10% is the core of your business, the bits of data you can’t expose directly to the client for them to tinker with – things like account numbers and product prices. This might not be critical for internal-facing reporting apps like Mr. Driscoll’s dashboard app but for public-facing dynamic apps like EBay it’s the difference between success or crash and burn.

Furthermore, current web development teams are specialized for a reason. Front end programming has different demands and patterns than does server-side programming, and these are both very different than database design and programming. Startups and smaller teams might have rockstars who operate seamlessly across tiers, but these developers can be hard to find. So even though JavaScript might be a common language across application tiers, the reality is that as your team grows you’ll still need specialized developers to be effective across all three.

Lastly, even though node.js promises performant asynchronous application design, the truth is that many developers face a steep learning curve before they can be effective programming (and debugging) in asynchronous environments. Like Java threading before it, asynchronous programming will likely find its niche solving certain problems but never become mainstream. Or it will be hidden behind so many layers of framework programming as to be nearly unrecognizable and totally unusable.

So LAMP is far from dead. It will persist exactly because it’s a perfectly tuned commodity solution in a market that values commodity solutions (e.g. Google’s famed server farms). It’s the UNIX of the web layer, encouraging extensible designs by nature of its simplicity and interoperability.

Every age has its upstart, and this age is no different. But to win the upstart has to bring more to the table than the established solution, and it remains to be seen whether the JavaScript stack has what it takes to displace the LAMP juggernaut.

0 comments

Bitcoin, Mt. Gox, and 8 Lines of Code

In an article I had published in infoTech Spotlight discussing security and the Gawker database hack, I argued that it’s relatively easy to protect your user’s personal data against a database breach. The idea isn’t new – as a matter of fact this particular implementation dates back to 2005, and you can be sure it was known well before then.

Faced with a similar breach, Mt. Gox appears to have performed a little better. Although they originally depended on md5() hashing to secure their passwords (warning: do not do that), they came to their senses and started salting individual passwords much the same way as this article recommends.

Good for them. This is a great case study on how an organization who borked it was able to retrofit their code to protect their users. I applaud them for that effort. It may not have been perfect, but it was likely good enough for users who were smart enough to protect an account on a financial exchange with a half-way decent password.

As an aside, it’s a little disturbing how many of the nerds on the Hacker News don’t understand that not only is it ok to store the salt alongside the encrypted passwords in your database, it’s actually a good idea. Ugh. Another reason why developers should never be trusted to roll their own authentication schemes.

Unfortunately, Mt. Gox’s security lapse has come at a crucial point for Bitcoin. Bitcoin is an interesting economic experiment. I encourage you to read up about it as the official docs can explain it much better than I can here.

While it’s strictly true that Mt. Gox != Bitcoin, at this point in the evolution of the movement few people have the sophistication to understand the difference. So it might not be fair, but it’s still entirely possible that this incident could torpedo the movement. That’s unfortunate for many reasons, but it’s a reality of the world we live in. An upstart economy can’t prevail without trust.

It seems that 8 lines of code may not be enough.

0 comments

On Mace Windu’s Two Catastrophic Errors

I probably spend way too much time thinking about this, but every time I watch either Episodes 2 or 3 I’m left with the feeling that the key tragic sequences in the series both involve Mace Windu.

The first one is the most obvious. In Episode 3 he had a chance to kill Palpatine straight up but hesitated, leading to his bungee jump out of the Chancellor’s office without a bungee cord after Anakin’s betrayal. Cool cat, but died like a punk really.

The less obvious one is his beheading of Jango Fett in Episode 2. Don’t get me wrong, the Geonosis sequence is probably one of the best fight scenes in the prequels. But if you think about it, Jango was the weak link in all of Palpatine’s plans. There were probably only 3 characters in the whole galaxy that knew the details of Palpatine’s gambit to rule the galaxy by playing both the Republic and the Separatists against the Jedi. The first was Palpatine himself. The second was arguably Dooku, who lead the straw-man Separatist movement until Anakin relieved his shoulders of his head. The last had to be Jango, who was the source of the clones used by Palpatine as well as Dooku’s bodyguard on Geonosis. Capturing instead of killing Jango could have unraveled the whole plot.

But even still, it strikes me as unbelievable that at least Obi-Wan, if not Yoda and Mace, wouldn’t have been able to connect the dots on Jango. Obi-wan confronted him on Kamino and then sees him again on Geonosis. It probably doesn’t take too much brain power to wonder why the guy’s popping up on both sides of the fence.

0 comments

Facebook Status Updates and Infinite Session Keys

Anyone have the first clue as to why Facebook’s developer documentation sucks so hard?

I was developing a simple Facebook application for one of my company’s clients that required me to update a user’s status via a scheduled background process. The developer documentation lead me down all kinds of paths by referencing infinite session keys and the “keep me logged in” check box. So I scoured the internets for some examples, only to find that there aren’t many. All these claims that bajillions of people are creating Facebook apps and not a single one of them that are updating a user’s status offline can document it? ARRRGGG!

So, here is what I hope will save someone else a ton of time – a real life, working code sample for updating a user’s Facebook status offline. Careful – make no sudden moves or you might scare this rare beast back into hiding.

Our app is requesting two extended permissions – “offline_access” and “status_update”. This is also using Elliot Haughin’s Facebook plugin for CodeIgniter. Elliot’s package includes an older version of the Facebook PHP Library, so I had to grab the latest version from Facebook and drop it in place. Other than that it was easy to integrate this into my app.

//http://wiki.developers.facebook.com/index.php/Users.hasAppPermission
//must be one of:
//   email, read_stream, publish_stream, offline_access, status_update, photo_upload, 
//   create_event, rsvp_event, sms, video_upload, create_note, share_item
if( $this->facebook_connect->client->users_hasAppPermission("offline_access", $fbUID) &&
    $this->facebook_connect->client->users_hasAppPermission("status_update", $fbUID) ){
    $this->facebook_connect->client->users_setStatus("some status message", $fbUID); 
}

Seriously, that’s it! All those posts, all that searching – for 3 lines of code! The key point that was conveniently left out of other articles is that there is no “session key” required now. Facebook is smart enough to know that the user granted the app permission for offline_access and status_update, so you only need to send the user’s Facebook ID. Moley.

Another annoyance. They make a big deal out of the fact that they provide a REST-ful interface, but none of the examples in their documentation show the format of the REST request (although they do at least provide the REST server URL and a handy hint to include the “Content-Type: application/x-www-form-urlencoded” header). Yes, I get it, you want me to use the PHP Library, which is nicely designed. But for quick and dirty testing I like to whip up some curl commands. If I don’t know how to format the XML I can’t easily do that. Bah!

4 comments

NULL is NOT a valid state

I’m amazed at the amount of code that I see that contains uninitialized variables. I can’t think of a bigger bang-for-the-buck habit you can fall into than taking an extra 2 seconds to properly initialize whatever variable you’ve created. Look, I know a lot of ORM layers use NULL variables as a flag to insert/select/update null values. I get it. I don’t love it, but I get it. Other than that, I can’t think of a single reason to not initialize your variables. Unless you love NullPointerExceptions, or security exploits, or constantly having to check for null before you call a method on an object you just got back, or who know whatever else people have done to themselves because they were to lazy to add ” = 0;” after their variable declarations. Coding is hard enough as it is. This just makes it harder.

0 comments

Psychotic Home Page Design Syndrome

In an earlier post I referred to the tendency of a site’s home page to speak volumes about the character and and principles. I call this Psychotic Home Pager Design Syndrome. There are a couple of great examples of this, but the ones that stand out best to me are sites like GoDaddy.com, ESPN.com, and MLB.com. Imagine you are someone coming to the home page of one of those sites looking for a very specific product. Imagine trying to find that product in the mess of boxes and links and images and ads. It’s impossible.

One might argue that these companies have tons of products, and the home page reflects the need to have their most successful products featured and touted. Exactly. Having worked at MLB.com, I can tell you exactly how this happens. You have 2 distinct business units with shiny products that represent some business interest. You have 2 product managers who equate sales of their product with the size of their year end bonus. You have endless campaigning to have your product featured on the home page, where it will get the most traffic. You have exactly 1 CEO who doesn’t really want to have the product managers draw short straws because, afterall, it’s just pixels on a page. So the end result is a mish-mash of products and services that speaks more to the internal structure of the company than to usability.

Contrast this to a company that gets a lot of fanboys/good press – 37Signals. I won’t go into details here about my thoughts on the 37Signals hype (that should tell you enough), but for a company with a good smattering of products their home page is simple and usable. In the context of what we know of the internals of their company, this makes a ton of sense.

0 comments

Request Translation

Request: Can you give me expected adoption rates of the new XYZ feature so we can estimate whether we have sufficient capacity to handle incoming traffic?

Translation: Can you pretend to understand the unknowable well enough to pull a random but superficially believable number out of your ass which I will crucify you with later on if it turns out that whatever I did to prepare was insufficient and/or people generally believe that the failure was my fault.

0 comments

PHP Frameworks and Scaling

This article covering a talk by Rasmus Lerdorf on the issue of scaling PHP and PHP Frameworks is a couple of months old but keeps popping up on Delicious. There’s a lot to disagree with there, especially if you read through the comments by other people who were in the audience for the talk, but the thing that stood out for me benchmarking covered in the “Hello World” section.

Please please please tell me the reporter misunderstood Rasmus’ point, as some have suggested in the comments section. I can only hope Rasmus (who, btw, is a vocal member of the Nike+ Running community that I work on at R/GA and has written the SlowGeek site to improve on some features he felt we were lacking) would not make a big deal out of such a naive example. So you’re telling me that “Hello World” printed out directly from a PHP file is orders of magnitude quicker than “Hello World” printed out through a PHP Framework? Amazing. I will immediately concede that if your intention is to write and scale a “Hello World” application CodeIgniter or other PHP frameworks are not for you.

It’s like saying that it takes longer to get to the corner store if you take you helicopter as opposed to walking. Sure, you have to suit up, start up the rotors, take off, find a good landing spot, step over the dead bodies, etc. But that’s not practical is it? Either is a “Hello World” example.

Look, I’m perfectly willing to accept that CodeIgniter will be slower than a hand-crafted framework when all is said and done. That alone is the reason I don’t use any ORM in my code. It can’t possibly be faster. But for something at my scale it makes configuration, development, and maintenance very easy. And in the wise words of the fine developers at Coding Horror, programmers are expensive and hardware is cheap. To a certain scale, you can just throw hardware at your problem.

That said, I’m sure Rasmus understands that and the reporter took him out of context. Right….?

4 comments

One Flag to Rule Them All

So right now I’m looking at a table that has at least 3 different columns that control whether the particular row is displayed on the front end. In some cases that’s unavoidable, but it has to be kept in check.

Maybe you can tell me what the difference is between the intent of these columns: status (e.g. pending, active, canceled) and should_display (0 or 1). In addition to that, there’s one part of the code that will ignore a record if one of the FK columns is null but will consider it if it’s non null.

This is madness. I now have to piece together which columns are significant to which consumers of the data. And then I have to figure out the magical combination of values to make the row appear on the front end. This leads me to some quick rules for database flags:

  • Limit the number of display flags to as few as possible. I usually use a is_active or display_order column to determine whether the row should be retrieved. There will be cases where the row should be retrieved by one consumer and not another, but there should never be more than one column that does almost the same thing.
  • Use descriptive column names. The ones above are too general. is_active tells me exactly what I need to know.
  • You can use a nullable timestamp column to do both boolean checks and date-triggered checks. In other words, if the column is null it means the column is still valid. If it’s not null you have to check it against the current timestamp. This saves a duplicated column and is fairly easy to get across.
1 comments

Magic Button Syndrome

If there’s one concept I’ve fought my entire career it’s that there can be, or even should be, a way to make everything work “automagically”, a term the afflicted developers use lovingly. I recently christened this the “Magic Button Syndrome”.

Usually a bunch of fairly smart developers sit in a room and start dreaming of how a system might work. “We have to make sure we can easily modify the configuration,” one might say. “We should have a means to generate the configuration based on some other configuration file,” another might respond. “Let’s use annotations to make sure that the configurations stay in sync across versions,” someone else might suggest. Yet another person might think it’d be wonderfully cool if you could auto-inject annotations somehow.

Their triumphant moment comes when the CTO is standing over their shoulder screaming about something that needs to be fixed ASAP and they nonchallantly say, “Oh, I can fix that, one second.” They turn to their machines dramatically, edit one or two lines somewhere, smack the return key, twiddle their thumbs, reload the page, and then smile. “No big deal,” they’ll say with a smirk on their face. That’s it. That’s what they live for. They want that one Magic Button moment.

It sounds foolish, but there are plenty of developers like that out there. For these people, it makes perfect sense that if you can automate something little, automating something bigger containing tons of moving parts must be even better. Eventually the automation will reach singularity in the Magic Button.

The problem is that automation suffers from the same law of diminishing returns as does traveling at the speed of light. It takes an infinite amount of energy to accelerate a particle with any mass to the speed of light. In the same way, it takes an infinite amount of energy to create that Magic Button. Not that it stops people from trying. Sure, changing one of the thousands of options that are contained in a config file or database is easy. But if you’ve worked on systems like these you know that doing anything outside of the realm of what the system was designed to do is absolutely, unbearably painful. That Magic Button hides layers of abstraction upon abstraction upon abstraction. Just when you begin to understand what a peice of code does you realize you forgot what code is calling it. In the effort to make something of uber-value, no single component makes any sense.

You find it takes people months to really understand the system. Changes take weeks to test, and lead to reprecussions that no one really ever expected. Once all the original developers are gone everyone starts to realize the system needs to be redesigned. It’s become like the pyramids – beautiful, absolutely brilliantly designed, but a total mystery. This time we’ll do it differently. In Ruby maybe. And auto generate all the documentation using XML…

0 comments

Next Page »