Tag: programming
Backwards Compatibility
Ivo already pointed this out, but I want to point it out again: Boy Baukema writes a very nice entry regarding backwards compatibility on the ibuildings.nl corporate blog.
Backwards compatibility (BC) is a tricky thing to support, even when you strive hard to, as Boy puts it, "think hard about your API" prior to release. Somebody will always come along and point out ways it could have been done better or ways it could be improved. I've had to wrestle with these issues a ton since joining the Zend Framework team, and while it often feels like the wrong thing to do to tell somebody, "too little, too late" when they have genuinely good feedback for you, its often in the best interest of the many users already using a component.
I had the pleasure of meeting Boy last year when visiting the ibuildings.nl offices, and he's got a good head on his shoulders. He does a nice job outlining the issues and a number of approaches to BC; if you develop a project for public consumption, you should definitely head over and read what he has to say.
Apache HOSTNAME on Clusters
In an effort to debug issues on a cluster, I was trying to determine which machine on the cluster was causing the issue. My idea was that I could insert a header token identifying the server.
My first idea was to add the directive Header add X-Server-Ip "%{SERVER\_ADDR}e
in my httpd.conf
. However, due to the nature of our load
balancer, Apache was somehow resolving this to the load balancer IP address on
all machines of the cluster — which was really, really not useful.
I finally stumbled on a good solution, however: you can set environment
variables in apachectl
, and then pass them into the Apache environment using the
PassEnv
directive from mod_env
; once that's done, you can use the environment
variable anywhere.
In my apachectl
, I added the line export HOSTNAME=\
hostname``. Then, in my
httpd.conf
, I added first the line PassEnv HOSTNAME
, followed by the
directive Header add X-Server-Name "%{HOSTNAME}e"
. Voilá! I now had the
hostname in the header, which gave me the information I needed for debugging.
2007 Retrospective
2007 was a busy year, both personally and professionally. I won't go into the personal too much, because, well, it's personal, and some of the details are simply inappropriate for blogging material.
Here's the short version:
- One trip to Belgium and The Netherlands.
- Two trips to Israel.
- Two trips to Atlanta, GA (not counting the return trip from Europe, when I was stranded for a day due to storms in the Northeast).
- Three different user groups attended, with three presentations.
- One major Zend Framework release
- One PEAR release.
- One podcast.
- One webinar.
- One book published.
- One conference attended.
What follows is my month-by-month breakdown:
svn:externals
I was recently working with someone who was using Zend Framework in their project. To keep things stable and releasable, he was doing an export of framework into his repository and checking it in. Since files change so much in the ZF project currently, instead of doing an rsync from a checkout into his own repository, he decided instead to delete the directory from the repository and re-add it everytime he was updating framework.
This seemed really inefficient to me, especially considering that it made it incredibly difficult to merge changes from his development branch into his production branch (deleting and re-adding directories breaks the merge process considerably). I knew there had to be a better way.
I'd heard of the svn:externals
property before, but never really played with
it. As it turns out, it exists for just this very type of situation. The
problem is that the documentation of svn:externals
in the SVN book doesn't indicate at all how the property should be set, and
most howto's I've read omit one or more very important details. I finally
figured things out through some trial and error of my own, so I'm going to
share the process so others hopefully can learn from the experience as well.
It's actually pretty easy. This assumes that your project layout looks something like this:
project/
branch/
production/
tag/
trunk/
-
In the top of your project trunk, execute the following:
$ svn propedit svn:externals .
-
This will open an editor session. In the file opened by your editor, each line indicates a different external svn repo to pull. The first segment of the line is the directory where you want the pull to exist. The last segment is the svn repo URL to pull. You can have an optional middle argument indicating the revision to use. Some examples:
-
Pull framework repo from head:
framework http://framework.zend.com/svn/framework/trunk
- Pull framework repo from revision 2616:
framework -r2616 http://framework.zend.com/svn/framework/trunk
-
-
After saving and exiting, update the repo:
$ svn up
-
Commit changes:
$ svn commit
One thing to note: any directory you specify for an svn:externals
checkout
should not already exist in your repository. If it does, you will get an
error like the following:
svn: Working copy 'sharedproject' locked
svn: run 'svn cleanup' to remove locks
I show using revisions above; you could also pin to tags by simply checkout the external repository from a given tag. Either way works well.
Then, when moving from one branch to another, or from the trunk to a branch,
you simply set a different svn:externals
for each branch. For instance, your
current production might check from one particular revision, but your trunk
might simply track head; you then simply determine what the current revision
being used is on your trunk, and update svn:externals in your production branch
when you're ready to push changes in.
Hope this helps some of you out there!
Vim 7 code completion
I may work at Zend, but I've never been a fan of IDEs. They simply don't suit my programming style. I can usually keep track of file locations in my head pretty easily, and what I really need is a blank slate on which I can write, and one that doesn't consume resource that can better be used running web servers and other programs. Syntax highlighting, good indentation — these are important, but you can get these from good, minimal text editors very easily. Vim is my editor of choice.
I will admit, though, that one area where I have had IDE-envy is the area of code completion. I often find myself doing quick lookups to php.net or perldoc to determine the order of arguments to a function or method call, or checking for the expected return value. Most of the time, this doesn't take much time, however, so I just live with it.
Today, however, cruising through the blogosphere, I came across an article showcasing some new features of Vim 7.0, and discovered Vim 7's code completion.
Basically, while in insert mode, you can type <C-x> <C-o>
to have vim attempt to autocomplete the current keyword. If more than one possibility exists, it shows a dropdown, and you can use your arrow keys to highlight the keyword that you wish to use.
But it gets better! Not only does it do this kind of autocompletion, but it also opens a small 'scratch preview' pane showing the function/method signature — i.e., the expected arguments and return value!
I thought I had little need for IDEs before… now I have even less! Bram and the rest of the Vim team, my hat's off to you for more fine work!
Serendipity upgrade
I upgraded Serendipity today, due to the recent announcement of the 1.0 release, as well as to combat some rampant issues with trackback spam.
I've been very happy with Serendipity so far; it just runs, and the default install gives just what you need to get a blog up and running, and nothing more; any extra functionality comes via plugins which you, the blogger, get to decide upon.
Additionally, it's incredibly easy to upgrade. Unpack the tarball, rsync it over your existing install (I rsync it, because I don't use 'serendipity' as my directory name), visit the admin, boom, you're done. I've upgraded several times, and never lost data, nor configuration settings.
My primary reason for the upgrade was, as noted earlier, to combat trackback spam. As of this morning, I had 15,000 pending trackbacks, none of which appeared to be valid (if any of them were, and you're not seeing yours, I'm very sorry; I deleted them en masse). These had accumulated in less than a month — that's an average of about one every 3 minutes.
Since upgrading, and using the Akismet service, I've received not a single spam trackback. Needless to say, I'm happy I performed the upgrade!
If you're a Serendipity user, and haven't upgraded to 1.0.0 yet (or one of it's reportedly very stable release candidates), do it today — you have nothing to lose, and a lot of lost time to gain!
The light has not set on PHP
I ran across a blog post entitled "Why the Light Has Gone Out on LAMP" earlier today, and felt compelled to respond.
First, a rant: somehow, this article got posted on Slashdot. I've never heard of the guy who posted it, and some quick googling shows that he's a pythoner. He's simply fueling the language wars, and the slashdot post opened up a huge debate that need not have occurred. I think it was irresponsible of the Slashdot editors to post it.
In the post, the author makes an analogy of using PHP + MySQL as the equivalent of using BASIC, and then uses a quote that claims BASIC "has become the leading cause of brain-damage in proto-hackers."
I'm sorry, but using a language doesn't cause brain damage. And there are many levels to programming. And using Python, Ruby, C, C++, Java, etc., does not automatically make you a better programmer than those using one of "those other languages". You can write crap code in any language. You can also write great code in just about any language.
Programming takes practice; programming well takes a lot of practice. You get better at it by learning more about programming practices, and applying them to your language. Part of programming is also learning when a particular language is suited to a task, and when it isn't. Python works for the web, but it's not particularly suited to it; similarly, you can write web servers in PHP, but that doesn't mean you should.
Stop the language wars already! Stop writing incendiary pieces about a language you don't use regularly or never gained particular proficiency in, and code already!
Telcos are Attacking the Internet
I generally try to stay out of politics on this blog, but this time something has to be said, as it affects anyone who uses the internet, at least in the US.
Basically, a number of telcos and cable providers are talking about charging internet content providers — the places you browse to on the internet, places like Google, Yahoo!, Amazon, etc. — fees to ensure bandwidth to their sites. Their argument is that these content providers are getting a 'free ride' on their lines, and generating a lot of traffic themselves, and should thus be paying for the cost of bandwidth.
This is patently ridiculous. Content providers already have to pay for their bandwidth — they, too, have ISPs or agreements with telcos in place, either explicitly or via their hosting providers. Sure, some of them, particularly search engines, send out robots in order to index or find content, but, again, they're paying for the bandwidth those robots generate. Additionally, people using the internet are typically paying for bandwidth as well, through their relationship with their ISP. What this amounts to is the telcos getting paid not just by each person to whom they provide internet access, but every end point on the internet, at least those within the US.
What this is really about is telcos wanting more money, and wanting to push their own content. As an example, let's say your ISP is AOL. AOL is part of Time Warner, and thus has ties to those media sources. Now, those media sources may put pressure on AOL to reduce bandwidth to sites operated by ABC, CBS, NBC, FOX, Disney, PBS, etc. This might mean that your kid can no longer visit the Sesame Street website reliably, because AOL has reduced the amount of bandwidth allowed to that service — but any media site in the TWC would get optimal access, so they could get to Cartoon Network. Not to slam Cartoon Network (I love it), but would you rather have your kid visiting cartoonnetwork.com or pbskids.org? Basically, content providers would not need to compete based on the value of their content, but on who they can get to subscribe to their service.
Here's another idea: your ISP is MSN. You want to use Google… but MSN has limited the bandwidth to Google because it's a competitor, and won't accept any amount of money to increase that bandwidth. They do the same with Yahoo! So, now you're limited to MSN search, because that's the only one that responds reliably — regardless of whether or not you like their search results. By doing so, they've just artificially inflated the value of their search engine — without needing to compete based on merit.
Additionally, let's say Barnes and Noble has paid MSN to ensure good bandwidth, but part of that agreement is a non-compete clause. Now you find your connections to Amazon timing out, meaning that you can't even see which book provider has the better price on the book you want; you're stuck looking and buying from B&N.
Now, let's look at something a little more close to home for those of us developing web applications. There have been a number of success stories the last few years: MySpace, Digg, and Flickr all come to mind. Would these endeavors have been as successful had they needed to pay multiple times for bandwidth, once to their ISP and once each to each telco charging for content providers? Indeed, some of these are still free services — how would they ever have been able to pay the extra amounts to the telcos in the first place?
So, basically, the only winners here are the telcos.
Considering how ludicrous this scheme is, one must be thinking, isn't the US Government going to step in and regulate against such behaviour? The answer, sadly, is no. The GOP doesn't like regulation, and so they want market forces to decide. Sadly, what this will likely do is force a number of content providers to offshore their internet operations — which is likely to have some pretty negative effects on the economy.
The decision isn't final — efforts can still be made to prevent it (the above link references a Senate committee meeting; there's been no vote on it). Call your representatives today and give them an earful. Tell them it's not just about regulation of the industry, but about fair competition in the market. Allowing the telcos to extort money from content providers will only reduce the US' economic chances in the world, and stifle innovation and choice.
XP + Cygwin + coLinux == Productivity
I wrote earlier of my experiences using Windows XP, a move I've considered somewhat unfortunate but necessary. I've added a couple more tools to my toolbox since that have made the environment even better.
Using Windows XP
Those of you who know me well know that I've been using Linux as my primary OS for many years now. At this point, for me, using Windows is like deciding I'm going to use a limited vocabulary; I can get the idea across, but not quite as well.
Due to the nature of where I work and the fact that I'm telecommuting, I've been having to maintain a dual-boot system. I use Ubuntu for my daily OS, and boot into Windows when I need to interact with people at work via Webex or Skype (we're using the new Skype beta with video, and it only works on Windows XP at this time).
This week, however, I've had to stay on Windows quite a bit — lots of impromptu conference calls and such. So, I've been customizing my environment, and been pretty pleased with the results.
Continue reading for some tips on customizing your Windows XP environment to work and feel a little more like… linux.