Wednesday, November 2, 2011

is that an atom in your server?

I got a big power bill the other day.

You probably did too (gotta love that carbon tax), but mine was just for my office. And I hadn't been using the air conditioner a whole lot.

Conclusion: the "server" I'm running 24x7 is using too much power.

It's a Dell Vostro 200 (i.e. a retired desktop workhorse) with a Core 2 Duo CPU and dual 3.5" hard drives. It runs Linux and hosts SSH, NTP, DHCP, DNS, TFTP, SMTP, IMAP, VoIP (Asterisk), CVS, iptables and rsync. Not a lot, in other words, but it does need to run all day every day.

Anyway, now that I have a dedicated NAS for storage (a surprisingly impressive Netgear ReadyNAS NV+), I thought I'd try replacing my power-hungry Vostro 200 with an Atom-based SSD server.

Atom processors are usually found in netbooks, and what they lack in processing power they make up for in super-low power consumption. They're also CHEAP.

Here's what I bought:

Antec ISK 310-150 Mini-ITX Case
ASUS AT5NM10T-I Mini-ITX Motherboard
Corsair 2GB DDR3 SO-DIMM x 2
OCZ Vertex 2 60GB SSD
Intel PCIe Gigabit Ethernet Adapter

Happily, it has plenty of spare processing power for my purposes. I daresay many servers (and even more desktops) could be deployed with Atom processors without the sky falling.

Go Green. Go Atom.

Sunday, September 11, 2011

php beautification

I'm a little bit OCD.

Certain things have to be perfect for me to be a functional human, and one of them, unfortunately, is the formatting of my code.

Before text editors had automatic indenting and other OCD-friendly coding aids, this was more than a little problematic for my productivity.

That said, it's 2011, and it's still not easy to find the perfect PHP formatter. They tend to either break your code (e.g. phpDesigner's inability to cope with "continue 2" [fixed in version 8]), require the use of a bloated IDE (e.g. Zend Studio), offer an inadequate set of options (e.g. most of the formatters Google knows about) or only work online (hello IP infringement). As an added bonus, there aren't any cross-platform options (except Zend Studio, which I can't stand).

The best solution I've found so far is WaterProof's phpCodeBeautifier. It's PC-only (although they do offer a Linux version, so I'm hoping they'll compile an OS X one eventually), it plays nice with PHP5 (including late static binding), it's fast (especially when wrapped up in a batch script) and it's free!

Here's the batch script I'm using:


@echo off

copy /y %1 %1.phpCB

C:\util\phpCB --space-after-start-bracket --space-before-end-bracket --space-after-if --space-after-switch --space-after-while --space-before-start-angle-bracket --space-after-end-angle-bracket --extra-padding-for-case-statement --one-true-brace-function-declaration --glue-arrow --indent-with-tab --force-large-php-code-tag --force-true-false-null-contant-lowercase --align-equal-statements --optimize-eol --one-true-brace --rewrite-only-documentation-comment --comment-rendering-style PEAR --padding-char-count 1 %1.phpCB > %1

del %1.phpCB


You'll thank me later.

Tuesday, July 5, 2011

why you shouldn't buy a kogan agora tablet

Like so many others, I couldn't resist the allure of an Android tablet priced well below $200, as Kogan's new tablet was pre-launch. Its specs looked good, the one review available was favourable, and as an iOS user with various iDevices, I was keen to experience/test/develop for the Alternative Mobile Platform.

Eventually, my pre-ordered Kogan Agora 7" tablet PC arrived. Happily, it was pretty much on schedule (others weren't so lucky, according to Kogan's Facebook wall). Less happily, it wasn't functional enough to keep. Thank goodness for Kogan's 7-day money back guarantee.

For starters, I couldn't get it to start up without using the reset button on the back. At first I thought it was just waiting for its first full charge, but nothing changed when the charging light turned green, so I tried the reset button. I needed to use it EVERY time the tablet went to sleep. (To be fair, Kogan did offer to replace my tablet when I described this to them, but there were other problems too.)

When the tablet wasn't in a deep sleep, it performed reasonably well. It felt good to hold, buttons responded well, apps ran at a respectable pace, and the screen wasn't nearly as nasty as CNET reported. That said, there were a couple of problems that were deal-breakers for me. Obviously a tablet this cheap isn't going to be anywhere near as polished as the iPad, but I was hoping it would be reasonably functional, and it just ... wasn't.

First, and most significantly, the accuracy of the touchscreen near the edges was abysmal, which made it nearly impossible to type anything accurately with the on-screen keyboard. Depending on the orientation of the tablet, it was up to a full centimetre out, and no calibration utility was available. No, I wasn't planning to write any novels on my tablet, but being unable to type so much as a tweet without frustration made it unusable for, well, pretty much everything except media playback.

Second, the orientation sensor was possessed. Slight movements in any direction - well away from the ambiguity of being near-horizontal - would throw the tablet's screen upside down or spin it to the wrong orientation. Again, Android's accelerometer calibration utility was unavailable; the only workaround offered by Kogan was to disable the "Auto-rotate screen" option. This worked, as long as I was content to work in portrait orientation only. I wasn't.

Finally, the camera was utter rubbish. Not only was it located at the bottom of the tablet, forcing you to either aim it up your nose or hold it upside down (pity about that orientation lock!), it drastically underexposed my face in typical indoor light. So, web conferencing with the Kogan tablet was a total no-go.

Build quality? Good. Processing power? Great. User experience? Very very bad. Don't waste your money. In the same price bracket, you can buy an Archos 70 with Android 2.2 and similar specs that ACTUALLY WORKS. Mine arrived today. It's no iPad, but it's a very cheap, very functional Android tablet. Highly recommended.

Friday, May 6, 2011

asus 1215t: a rather impressive netbook

Sorry, this post isn't about writing software, although it does relate to my acquisition of a PC exclusively for development that can't be done on my Mac ;)

I was looking for a netbook that was:

  • cheap
  • hi-res (i.e. 1366x768 - not much by notebook standards, but plenty by netbook standards, and enough for my purposes)
  • capable of driving a large external monitor (for those coding sessions when I need lots of pixels)
  • large enough to type fast on (12+ inches)
  • faster than a single-core Atom-based netbook

As I discovered, there aren't many hi-res netbooks out there, and most are pretty pricy.

Eventually I noticed that B&H - from whom I buy a fair bit of camera gear - sell netbooks, and carry the ASUS 1215T, an AMD-based netbook that ticked all of my boxes, with Windows 7 and a dedicated graphics card to boot. So I ordered it in from the US (none of my Aussie suppliers carry it).

It's proving to be awesome bang for buck. Obviously it bogs down a little under intense CPU load, but development isn't very CPU-intensive, so that's not a big deal. Battery life is reasonable but not superb; again, not a big concern for me, and you'd expect a gruntier netbook to use more juice. The keyboard is up there with my 13" MacBook Pro in terms of feel, too ... not quite there, but very comfortable to use.

Anyway, consider this my personal recommendation for the 1215T. So good I imported two. (Actually that was just to make the shipping more worthwhile...)

Friday, April 8, 2011

so, you wanna deploy your schema?

Maintaining production databases is pretty easy when your product is running at a small number of sites, on systems you control, on identical platforms. Typically you'll maintain a set of SQL scripts that do the dirty work, deploy them to each site and run them at upgrade time. Depending on how savvy you are, you might even write SQL that checks whether or not each mod has already been applied, and moves on gracefully if so; non-destructive re-runnable SQL is always nice.

But what do you do when your product may be running at thousands of different sites, self-managed by end-users, on a variety of database platforms? Maintaining a bunch of SQL scripts - one for each platform - would be painful and near-impossible to test robustly.

Here's my solution, for what it's worth. I'm sure others have come up with something more elegant, but maybe you'll find this useful or interesting.

1. Establish syntax for a schema definition file

If we're going to create schemas we can deploy on any database platform, we're going to need a generic way of describing them, that can then be translated into platform-specific SQL at runtime by our management code. Whatever entities/data types/etc. we settle on are going to need to be supported by all platforms, too; so, simpler is better.

I'll spare you the full spec I came up with, but here's a snippet. There's no support for stored procedures or triggers, because I don't believe in burying business rules in the schema. Ever. As for views ... well, more on those later. For now, let's just say they'll appear in a different layer of this framework.

add table _user_config
add column _user_config.line_id int notnull primarykey identity
add column _user_config.setting_name varchar 50 notnull
add column _user_config.username varchar 50 notnull
add column _user_config.val text
add index _user_config.idx_user_config_setting unique setting_name,username
add index _user_config.idx_user_config_username username
add reference _user_config.ref_user_config_setting_name setting_name _config setting_name ondelete:cascade onupdate:cascade
add reference _user_config.ref_user_config_username username _users username ondelete:cascade onupdate:cascade

As you can see, it bears some resemblance to typical CREATE TABLE syntax, but each entity in the final schema occupies its own line. This is to make it easier to identify changes later on; e.g. if I were to add a column to this table, I could simply add a new "add column" line in place, and have management code detect it as an unapplied entry on existing installs (ADD COLUMN) or create it as part of a CREATE TABLE query on new installs.

There are "drop" directives too, and rules to aid in parsing, e.g. entities should be dropped after being added, so the schema manager will know not to create them in the first place on new installs.

2. Write schema management code

Sounds simple enough, right? It actually ended up being a non-trivial exercise (for me, anyway), but my schema_Manager class is now working. It has a Prepare method that works sequentially through a schema definition file, identifies new entries via a lookup table stored in a core database (yes, there are smarts to get that deployed before trying to store stuff in it), compiles them into instructions ready to pass to a platform-specific "provider" class, then uses the relevant provider class to build SQL ready to execute. An Execute method does the dirty work, handles errors and populates the lookup table.

3. Write platform-specific providers

For now, I've only written a MySQL provider, but additional ones should take about 2 hours each to add. All they do is build CREATE TABLE, ALTER COLUMN, etc. SQL for the schema manager to execute.

That's it! Obviously there's plenty of detail I'm not boring you with (maybe if I ever go open source with this project?), but hopefully that gives you some idea of how I've tackled schema deployment.

Feel free to hit me with questions or comments.

Saturday, April 2, 2011

javascript closures

As I've mentioned, I'm working on a JavaScript-heavy web app, and I'm re-learning Dojo along the way (it's been a couple of years). While I'm at it, I figured I should scrub up on my understanding of JavaScript closures.

So, here are the two resources I've found most helpful. Hope they help you.

The essentials:

http://www.javascriptkit.com/javatutors/closures.shtml

Achieving traditional OOP outcomes with closures:

http://www.crockford.com/javascript/private.html

Wednesday, March 30, 2011

which web app framework?

Here's what I wanted:

  • PHP backend: I know PHP is only a scripting language, but I want to sell this app to end-users who will self-host, and I don't want to make it too hard for them. PHP is cross-platform, ubiquitous, fast and dead-easy to deploy. It lacks strong typing, full-featured OOP and code compilation, but it meets my needs for this project.
  • Database independence: I'm happy with MySQL, but end-users might prefer SQL Server or something else.
  • Smart schema and data deployment: From experience, deploying schema upgrades and data updates safely and with minimal user involvement can be problematic. I particularly wanted a framework that could auto-detect pending schema changes and apply them, regardless of the age of the installed schema.
  • Simple persistence: Persistence frameworks tend to be code and metadata-heavy. I wanted to write SQL to retrieve object data and have the framework handle the rest, with optional hooks for validation and business rules available as needed. Most importantly, I wanted the persistence framework to play nice over RPC with JSON serialization.
  • Tight Dojo integration: There are many AJAX toolkits, but Dojo seems to be the most robust and mature when you're looking to move most of your view/controller code to the client-side. Its widget library, modular code, data handling and custom builds make it much more suitable for serious front-end development than jQuery etc., which are great for pretty effects and discrete code snippets, but not much more. Ideally, I wanted a server-side persistence framework with Dojo integration built-in.

Too much to ask? Yes, apparently.

None of the web application frameworks I found ticked enough boxes; most were too heavy on the server-side and too weak on the client side. Symfony2 was the best I could find.

So, I'm writing my own framework. More as I proceed.