Saturday, April 28, 2007

Murphy

So, I was going to write a bit more about the simplename gear, and I will, but I'm going to divert slightly for this post and talk about bugs.

Bugs happen. I don't write perfect code first time (and when I do, I get deeply suspicious of it), so I know that a certain percentage of my dev time is going to be spent correcting things.

There are a number of layers involved in this correction however. The first is simple stuff, typos, wrong function name etc that either get picked up by the validator or cause such a hideous mess that it's obvious there's a problem right there when you're doing the code. Increasing your efficiency here is basically only doable using smarter tools and being better with the language. I'm a vim fan so..well..my tools are pretty stupid, but I get by :)

The second layer is more subtle, logic problems etc hidden behind a decision tree that isn't easy to test. This is the area we try and cover off with test suites, trying to verify that things will actually work the way we want them to.

The problem with test-driven coding is that you actually have to write in a way that is testable, and it changes the way you code. I have found over time that by writing to be testable, you get more correct code for what it does, but you end up with an explosion of interfaces (in the programming sense, not the UI sense). An interface is what you call to test, so each segment of code is now bound to be an interface rather than a part of a whole.

This isn't bad per se, but the rule of leaky abstractions apply. As soon as you have to build an interface, you add a layer of concrete that is difficult to change, and through which communication becomes very constrained.

I tend to pick and choose my testing areas more carefully now. If it involves money or some other important thing, lots of automated testing up to the level of identification (ie, that an error has been identified and some kind of reasonable response can be made). If it's an odd-ball section or whatever, I don't worry about it.

The third layer though, these are the awful ones. I had one today. You get these bugs when the data you expect to receive from a seemingly trusted source does something completely unexpected when in a production environment, being accessed by someone from Guatemala.

There's nothing you can do about these, I lost a sale because of it. Only increasing maturity of your system will weed these out. Doesn't make it any less frustrating though.

For those people using Turbogears, the data you get from cherrypy.request.headerMap.get("X-Forwarded-For") and cherrypy.request.remoteHost is not what you expect under all circumstances. If you're relying on getting a single IP address as a result, vet the code rigorously as if the data were supplied by an idiot user :)

Friday, April 27, 2007

simplename

So Phi, what have you been up to recently? why have you been so quiet? no posts about supreme commander?

Ok, well, the main reason I've been so quiet (although not the only one of course, I went on holiday for a bit too) is because I've been hard at work on my new ... thing, simplename.

It's a .nz registrar with a few differences from your run of the mill ones like 2day and freeparking.

For a start, following on in the spirit of Exorsus, simplename is completely self-service. Not just registration, not just contact updates or delegation. Anything and everything you can do with a .nz domain from delegation, from renewal, transfer, even a complete change of registrant (something that normally requires phone calls and faxes and paperwork galore) can be completed on-line without having to wait.

Secondly, there's no logins or accounts. The entire system is designed with the domain consumer in mind, the kind of person who has up to around 3 or 4 .nz domains. So there are no logins or passwords to remember, the one thing you need is your UDAI, and the domain name, and you're set. I'll expand on this in a later post.

The final major point of difference is that it's entirely unassociated with web hosting or email. The service does .nz domain names, that's it. Obviously those of you with Exorsus accounts have no issues, or those with dns services located elsewhere (the majority of the people I've identified as most likely to turn up just because they know me). For everyone else, a new addition will be arriving shortly which will make live even simpler, but I'm trying not to talk about stuff I haven't done yet on the basis that thus far I've changed my mind at least 1000 times (conservative estimate) on just about every feature so we'll have to see.

I'm going to post a bit more on the way the whole thing works, and why I think it's cool later, but I'm just going to talk about one of my favorite tricks right now.

Any registrar has a bit of a race condition problem. The steps go like this:

1) Is domain available? YES
2) Charge creditcard
3) Register domain
4) Domain registration failed, someone managed to get in just after the availability check and now we're screwed

Now, there are a couple of approaches you can take, it's possible to register the domain first, then cancel it if the payment fails, however this has its own issues (think about what happens if a user tries to restart the register process because they closed their browser by accident). It's also possible to do an AUTH thing against the credit card, but my belief is - where money is concerned, simple is best.

The way I do it is that I have a coupon system built in, and in the event of a domain registration failure, the system will automatically generate a coupon code for the correct value and email it to the user so they can try again or get something else. It's a neat trick and saves the need for me to deal with credit card refunds (which are a pain), and lets the user get on with their stuff straight away without needing to try and interact with me (double win).

The final win is that while the service is shiny new, if anyone (Muggins) breaks anything, I can just send 'em a coupon to fix things up :)

More about the project and the system as a whole tomorrow some time.