" /> Bill de hÓra: March 2005 Archives

« February 2005 | Main | April 2005 »

March 31, 2005


Ian Bicking nails it:

"Resolving Python's problems with web programming is the most important thing we can do to market Python."

Take Ruby. Ruby is getting a lot of attention in the Java community because of Ruby oo Rails, especially because a few high-profile developers think it and ruby in general rocks. If you'd been working with Struts for the last few years, RoR is probably going to be highly appealing certainly compared to the incumbent JSF, or possibly even WebWork+SiteMesh.

Ian also said something comments that's worth highlighting:

"I personally have resisted the urge to develop a new framework (an urge I've felt many times over the years), and I actually am willing to give up my framework of choice for more conformity. But I can't abandon my framework (and I can't expect anyone else to do so either) -- other people have trusted my opinion and choice over the years, and it would be irresponsible of me to abandon them and those applications I've developed. Which is a bind a lot of us have probably been in."

Sounds like an Innovator's Dilemma - customer needs and invested legacy are stifling the ability to innovate. The thing is, what kills you in the end are the low end technologies. Always.

What I hadn't realized is that the web frameworks situation in Python is almost as diliuted as Java's. I wonder if this has as much to do with how we think about the web as the programming language we work in.


[Update: Mark Baker also points out that the technical debate was had. Mark doesn't think there is a middle ground: "IMO, there is none. 'Support both', which is how I'd characterize Dave's many well intentioned efforts to bridge the divide, is not a middle ground, since supporting both requires rejecting the interface constraint. "]

David Orchard seems like he's had enough of WS v REST:

"Every few months or so, another 100K or so of uninformed and sloppy writing is generated comparing Web services to REST. I've now found the analogy. It's the "war in Iraq."

If some of that uniformed and sloppy writing has been mine, I hope it will be pointed out to me!

My opinion on all that is this: I speculate REST advocates are smarting from the feeling of being brushed aside a few years ago. My impression is they might think WS folks weren't listening too much around the turn of the century, in much the same way Java and C# folks weren't listening about typing a few years ago. Toy stuff, not for real work. Safely ignored. I've seen comments made about the Web and the REST approach that have plain stung me as a practicing architect and developer, because I had built and encouraged others to build on the basis that these were sound. I have often imagined some people coming from the enterprise doubted the Web actually had an architecture - it was all HTML forms and Perl CGIs and MySQL (when MySQL was closer to journaled/indexed filesystem than a database) - not anything you could build real systems on. I still run into the odd person who's working off a 20thC WS playbook and thinks RPC and long-lived transactions are viable (whereas leading thinkers in WS have a different set of thoughts entirely).

Now, it seems that either on the merits, or on sheer popularity, the REST approach cannot be ignored. Where the small scale and consumer grade software technologies lead, the high-end invariably follows - any technology strategist knows that - the hard part is determining the time lines and executing transition. This is good because REST has lots of value for building cost-effective systems - but REST is not architecturally perfect either.

David again:

"In the Web services vs REST debate, the sad part is that the communities are not coming closer together. There are things that could be done for Web services to integrate with REST but few people from either camp are jumping up and down. And there certainly is no progress in getting to agreement on any kind of principled approach towards the discourse, like having an actual framework or architecture for evaluating the various arguments."

This is espousing a technical merits discussion, which is good. But it's not unfair to point out that Paul Prescod, Mark Baker, Rohit Khare, Jeff Bone and others had that debate years ago and got little thanks for it. Probably some people will not be bothered to do so this time around (you can justifiably decide that's bunk, but what the hey, this is an opinion piece after all). Plus the REST proponents will no doubt point out they already have an architecture for evaluating the arguments.

But if we were to have the debate as David is suggesting, there are some key areas and assumptions that could be re-examined on both sides.

With WS:

  • Protocol neutrality (why is this a good idea?)
  • XML Schema (more specifically the value of typed XML)
  • Identity (how many naming schemes do you need to go through?)
  • Objects to Documents (more specifically, WSDL backed tools)
  • Registries (why do UDDI et al still matter?)
  • Attachments (just what is the WS answer to MIME?)
  • Specification as strategy (interoperation not the place to relive the API wars)

With REST:

  • Security (Basic auth is just not good enough)
  • Gatewaying between HTTP and anything else (what should happen? Is CGI the best we can do?)
  • POST semantics (generic is not the same as meaningful)
  • Events (must we poll for everything?)
  • Reliable transfer (sometimes things have to get there)
  • Toolkits and frameworks (there's one, maybe two)

It does no harm to ask why the communities are not coming together - perhaps it is bad blood from years gone by, and possibly a lack of mutual respect. Still, it's not all bad. Some anti-WS folks may be banging the drums right now, but the conversation Jim Webber, Savas Parastatidis and Mark Baker have been having over the last year, has in my opinion been an extremely positive departure. We seem to be getting down to manageable number of WS rm specs, WSDL is being scrutinized. WS-Transfer is extremely positive. In my own corner of the world, I've had extremely thoughtful feedback on HTTPLR from folks on both sides of the fence.

There is the sense that people on both sides have gotten past the AI hokum aspects of the Semantic Web and are are looking at RDF/OWL as a practical basis for descriptive content formats. While transformation to my mind remains the default means to share data, I've always thought that RDF has potential as an interlingua.

March 29, 2005

Python preinstalled on ThinkPad

So, I'm there, unable to figure out why after installing the feedparser to the Python 2.4 install on this new laptop, I can't import it. It turns out the ThinkPad already had Python 2.2 preinstalled in C:/IBMTOOLS. It was at the top of the path, not 2.4 - I just hadn't paid attention to the version strings. Neat. I wonder what it's being used for.

PHP support, eh?

March 28, 2005

map() and list comprehensions

It looks likely that the lisp-style functions in Python such as map() will be removed, (along with lambda). The arguments for doing this seem to come down to two things: that you can use list comprehensions to provide the same functionality, and, that people don't like Lispisms (ie introducing them into Python way back when was a mistake that needs to be rectified). Various incidental arguments around speed also come up, but they don't matter.

I never fully understood the excitement around list comps when they were introduced. I suspect that because you can see just enough of the innards, a list comp is impressive, a bit like having a glass hood over a car engine or a perspex kettle. On the other hand , map() is opaque, even dull.

I imagine I like the map() approach because functions tend to nest and compose more elegantly than extra syntax. Removing top-level functions like map() from Python in favor of list comps fees like a step backwards. I don't see is how this:

  mods = [__import__(mod) for mod in testmodules]

is ever going to be more elegant than this:

  mods = map(__import__, testmodules)

No natural predator but your imagination

"When you're in a state of high-level fear, your brain devotes much of its resources to surviving. You go into survival mode. The lower centers of the brain recruit the higher centers of the brain to make sure you're not going to get killed. And you get a big volt of adrenaline and cortisol, and you go into very much black-and-white thinking, on or off, up or down. You lose the functions I was talking about earlier: flexibility; ability to see shades of gray, deal with uncertainty, have a sense of humor, entertain new ideas. All of that goes out the window, and you're just wanting to fix it, lest you be annihilated. That's good if you're being chased by a sabertooth tiger. It's not good if you're in your average daily work environment [...] They think they're working hard, and they think they're being productive, but they're not. They're busy, but they're not thoughtful. [...] How you allocate your time and your attention is crucial. What you pay attention to and for how long really makes a difference. If you're just paying attention to trivial e-mails for the majority of your time, you're wasting time and mental energy. It's the great seduction of the information age. You can create the illusion of doing work and of being productive and creative when you're not. You're just treading water." - Edward Hallowell

How many mailing lists? Part II

  • 6 internal Propylon lists
  • xml-dev
  • xml-dev
  • www-tag
  • nutch-dev
  • jython-dev
  • jython-users
  • ietf-announce
  • atom-syntax
  • atom-protocol

This is a lot less than 18 months ago, where I was up to about 35. I subscribe (har har) this drop-off to blog usage, the number of which in my aggregator has exploded in the last 12 months and will probably be in the low 1000s by the end of the year. Even the number of lists I need to monitor in work has dropped off, as we enable access to commit logs via RSS - first chance I get, ditto for the cruisecontrols build results.

There is no better way to absorb large amounts of information than RSS feeds through an aggregator. Now, all I need is a way to search weblogs. Maybe it's time to find out whatever happened to Infrasearch after it got sucked into JXTA.

March 27, 2005

Notes for setting up a development machine

The machine

So, the new laptop arrived. It's an IBM T42p with 1 GB of RAM, 60Gb HDD and a 15" screen. First impressions are positive; it feels right, well made. Very light. About 9Gb of the drive is given over to a restoration area leaving a working HDD of 50Gb. 35K pystone (was hoping for 38k but this is good enough).

I've never used a ThinkPad before, but we have a few IBM's in Propylon now and the feedback is positive. My old machine is an Inspiron 8500 and has been served me well enough. However it runs very, very hot without doing a whole lot; its motherboard burnt out late last year and I've singed my fingers on it more than once. I miss the Inspiron 8100 and 8200 machines; they were excellent allround desktop alternatives, albeit a tad heavy. They also had real keyboards not the spongey ones of the later generations.

I really like the percentage drain indicator for the battery on the taskbar, as the default Windows indicator is not that useful - nice touch. The battery itself does jut out of the back a bit instead of fitting flush with the unit, which is bit odd. Hitting the machine hard with Python or Java and the battery is good for 2 hours.

The IBM keyboard is nicely responsive, actually it's damn good. One problem: the fn key is outside the ctrl key - usually you put the most hit function keys to the edges where it's easy to find them. I can see it's going to take some getting used to (developers use shift and ctrl a lot when working). If I teach my hand to use it that will be a different motor action from all the other keyboards I use which makes swapping back and forth hard. Perhaps I should try to remap the keys... arggh - why do I even have to think about this?

That nit aside, the IBM feels like a solid, well-constructed machine. Onto the installation.


So, I want to document setting a dev new machine from scratch. Here are the things that need to be done:

  1. core setup
  2. Internet programs
  3. Programming tools and environment
  4. Editors
  5. Version control
  6. Working configuration
  7. Media

Computer name: picard.

Core installation. This will be an XP machine, since I find wndows more usable and expedient for laptops - once you install cygwin and win32all you have a decent hacking environment. Go through the usual windows XP stuff and after it boots, accept all the updates and turn on cleartype. Configure XP to accept updates automatically. Create one user called dehora - yes it's an administrator account (not sure windows is ready for underprivileged accounts just yet, maybe next year). Change the menu L&F to windows classic. Disable personalised menus (blech). Set the tab key to perform completion - oh, it's already there by default - cool. Install the CmdHere powertoy. Install Partition Magic and create a 30 Gb E:\ drive.

Install the OEM Office 2003 that came with machine. Do not install Publisher or Outlook. Install WinZip; install wzcline. Remove WinZip quickpick (why don't applications ask instead of putting themselves into your startup?)

My WLAN found the IBM with no fuss; configure it to accept the laptop via a MAC filter only.

Install the Andale Mono typeface. Don Box claims Lucida Console starts to work for code onscreen at >14pt and is good for presentations. At under 14pt (which is all programming) andale mono is the most beautiful typeface. It's the only programing typeface I've used for years - Lucida and Courier drive me nuts. This typeface is another reason I tend to develop on windows (my brain has been warped by art college so that typefaces matter way more to it than should be normal - I even call typefaces "typefaces" and not "fonts" for goodness sake).

Internet programs. First register the copy of Norton AV - but why just 90 days? This should be 12 months - for the amount of money you pay for a laptop, the subscription cost is amortized into irrelevance. I'll dump this after the weekend and use the company licence; if the meantime I want some kind of protection.

Onto Firefox and Thunderbird. I'm looking forward to setting up mail the least - it has tended to be problematic in the past. As well as that I've had two (very) long days helping a customer with a system after a hardware outage, so to be honest, I'm not much in the mood for goofing about with half a decade of mail (note to self: get Lucene to index this stuff someday). This time around I'd like to mount my Thunderbird mail on E:\ for backup purposes.

[Update: turns out you can use the Profile Manager to do just this. I copied my old profile from the Dell (it's huge, well over 2GB), edited the pref.js to fix up the embedded paths and pointed the profile at that folder and set it to be the default profile. Thunderbird picked it up just fine. Sweet.).

Install Skype - stop it listening on ports 80 and 443 for tunneling reasons (ugh). Install Gaim - log into jabber. Install smartftp. Install Winscp. Install RealVNC, but do not enable the server.

Programming tools and environment. Start with Cygwin and set HOME to point e:\home\dehora as home. Add cygwin to the path to get shell tools via the windows cmd. Run /usr/bin/chere to be add cygwin anywhere to explorer. Install Araxis merge.

Java. set JAVA_ROOT to e:\java - all things java will go undermeath. Install JDK1.3. JDK1.4 JDK1.5 in that order underneath JAVA_ROOT (Oh! Legacy!). Add JDK13_HOME, JDK14_HOME, JDK15_HOME to the environment. Set JAVA_HOME to point at JDK14_HOME for now. Copy ant 1.6.2 plus my extension jars for antant [1] into JAVA_HOME. Set ANT_HOME to correspond and add ANT_HOME\bin to the PATH. Install jython to %JAVA_ROOT%\jython. Then Ant-1.7beta, Junit, Xerces, Xalan, Sax2, Jini, Xt, Saxon, Findbugs, 1060-NetKernel, ActiveMQ, Joram, Svnant, Jena, JDepend, Lucene, Hibernate (the Java stuff de jour).

LAMP. Set LAMP_HOME to e:\lamp. Install MySQL 4, MySQL 3 (Oh! Legacy!), Ruby 1.8, Python 2.4 (+win32all +4suite) underneath it.

Install DrScheme. Install Erlang. Install OpenOffice (don't be fooled by the office productivity suite thing, it's really a development platorm :). Don't install VS.NET, SQL Server, or BizTalk 2004 just yet.

Editors: I have my ntemacs extensions and .emacs file checked into subversion as part of the default home folder. NTEmacs you just unzip and copy in the gnuserve executables to the bin folder. Textpad - tabs=2 spaces, scrub tabs for spaces, allow 1 instance, show line numbers, strip trailing whitespace, wordwrap on, install a .py, .sql and .xslt syntax file. IntelliJ - drop braces, 2 spaces, not tabs, show lines numbers, don't align anything. Ditto Eclipse - also plugin red-robin and PyDev for Jython/Python. Vim comes with cygwin, so I don't need to install that.

Version control. Install CVSNT. Install Apache using the windows installer and let it run on 80. Install subversion and tortoise - export/import the repositories from the old machine to this one, but this time use the native filestore (sfs) storage option instead of Berkeley db. Create SVN_ROOT as e:\home\svnroot. This is where the local svn repositories will go. Add this to httpd.conf and restart Apache via the monitor:

     <Location /svn>
	DAV svn
	SVNParentPath e:/home/svnroot

this lets Apache+DAV serve all folders below /svn as subversion repositories; more importantly it means you only have to edit httpd.conf once.

Working configuration: I do all my personal work in e:\home\dehora. I have a standard home folder which I check out from subversion. That gives me an extended bin directory for cygwin, encrypted password files, emacs extensions, documents, ssh settings, CVS settings and so on. It also means my entire home directory is under version control and is portable. This is good but for projects from other subversion repositories I'm working on in there, I need to escape those. So I add a projects folder and mark as ignorable in subversion; that way I work on projects inside my home folder without screwing things up. Add %HOME%\bin to the path.

Finally I setup an e:\home\propylon for for all things things Propylon. We have an infra projects for basic tools, scripts, configurations, ssh tunnels and so on. Check that out and add e:\home\propylon\bin to the PATH.

Media. Install FeedDemon, w.bloggar, WinAmp, Flickr uploadr, Acrobat Reader 7. Skip ITunes for now. (Must buy one of World of Warcraft or HalfLife 2... :) .

Total time: 5 hours. Would probabaly take about two if I was pulling files off a portable drive and had these notes organised more clearly.

[1] AntAnt is a tool for automatically generating a Java project structure and ant files via an ant script given some basic project details. I've been using it for years to produce standard project layouts, it's current home home is in Propylon's repositories. Very handy for both avoiding maven and reinventing wheels.


"If you look at software today, through the lens of the history of engineering, it's certainly engineering of a sort but it's the kind of engineering that people without the concept of the arch did. Most software today is very much like an Egyptian pyramid with millions of bricks piled on top of each other, with no structural integrity, but just done by brute force and thousands of slaves." - Alan Kay

March 21, 2005

POST Once Exactly

Mark Nottingham has evolved Click Submit Only Once as I-D. here's the abstract:

"This specification describes a pattern of use that allows HTTP clients to automatically retry POST requests in a manner that assures no unintended side effects will take place, and defines mechanisms to allow implementations to automatically determine when such patterns are supported." -draft-nottingham-http-poe-00

At first glance, it looks good. Mark's using headers to call out POE aware resources. I hope that every web framework on the planet will support POE - it's a must-have for forms submission.

March 20, 2005

There is no top

Stefan nails it on top-down versus bottom-up approaches to SOA:

"Easy enabling of your existing systems to allow them to play a role in your SOA may be a risk. But ignoring your systems sounds like the single worst strategic mistake you can make."

He's referring the John Crupi's [1] observation that bottom up SOA design is recipe for failure:

"It means that for SOA to be successful, it must be a 'top-down' approach. And top-down, means problem to architecture to solution. It does not mean, working from what we have and just wrapping it with new technologies just because we can. This bottom-up approach is quite natural and easy and is the perfect recipe for a SOA failure." - John Crupi

If John Crupi is trying to in part to say that taking an existing system (like a J2EE or .NET install) and waving some tool magic over it to expose your domain objects in terms of WS technologies, I would agree with that (much more work is needed as to how you expose an existing domain as services). I would also agree that the business needs to dictate its information and communication needs from IT and for too many years the tail has wagged the dog in that regard. However the statement he's made is somewhat broader - top down or fail. I was pretty surprised when I read it.

My tendency would be to believe the probability of failure is higher with a big, top down approach that has the ambition of spanning an enterprise. There are a few reference models and architectures for SOA available now and some of those are somewhat onerous, somewhat big. They involve the entire enterprise falling into line. I think it will be hard for any CIO or inward facing CTO to get on board with that approach, after the years of ERP and EAI hit and miss project failures and general IT overspend of the at the end of the 20th Century.

The difficulty with a solely top-down approach is that there is no top. SOA systems in reality tend to be decentralised - there's no one point of architectural leverage or governance, no one person who's going to be able to say and then enforce "a decision in ten minutes or the next one is free". Top-down approaches are necessarily centralised, and need to make assumptions about being able to coordinate activity amongst stakeholders which dents their usefulness in real environments. In the field, you'll will be communicating and working with partners with whom you no have no real leverage over in terms of specifying compatible technology or even processes. In some cases you won't just have no control over your callers, you'll have no idea who your callers actually are. Typically, partners will do the minimum amount of work necessary to communicate electronically (there are occasional exceptions to this, such as buy-side consortia). We have a good bit of experience of dealing with decentralised activities in Propylon and what strikes me as an approach that works in that context involves three things - focusing on finding the minimal necessary agreements, transforming data, and connector semantics. I see other efforts in the industry to be along the same lines but with different emphasis - focus on maximising the scope of agreements, concentrate on shared data semantics, ignore connector semantics [3]. Whether these are correlations or causes, I couldn't say, but they are worth keeping in mind.

The goal for any enterprise should be to wean off building big centralised systems and focus on how to network smaller more adaptable ones together [4]. It would help greatly if classically trained architects stopped killing good ideas for small and nimble systems by looking at them and saying "that'll never X", where X is some ility that may or may not matter in an operational context. And even if will matter, it might not matter yet, at least not so as to justify shouting down the approach. The reason in the past we needed to worry that 'it will never X' is because there is an assumption built into the procurement, requirements and development phases that systems of this kind get finished and that's it - no more money for active development. You have one shot to get it right. It turns out that 'one shot' is a myth and a dangerous one at that - business systems are never really finished, but thinking that they are radically affects thereafter how budget is dispensed and for what.

An important take-way from SOA thinking is related to the software lifecycle - that we're building Services, not Products. Services are ongoing entities that require continuous attention. People don't always appreciate why the likes of Google run extended betas, but if you spoke to an engineer there or in Amazon and asked them when they would be finished, well that might be a strange question. 'Finished' is an odd way of thinking about a service - they're either online or they're not. But in the enterprise developers building out services are asked every day when the service will be 'finished' - even though it's an equally odd idea there.

SOA is the first time the industry has taken the reality of ongoing systems maintenance and requirements variability and folded them into systems architecture. This is a critical step forward because the bulk of system cost is not found in the initial development. The other operational outcome of SOA (and WS) is that you don't really integrate until you go live - you can work in a staging environment to emulate the live one as much as you like, but it's just not the same thing because you won't have those actually calling your services to hand in staging. Staging is limited and building a parallel staging universe isn't tenable. The thing to do is to plan to fold development and testing into the live system (along with the staging phase), and be ready to work directly on live servers. I will concede that working on live servers is an idea that could make people deeply uncomfortable. It's not impossible to do, and is one reason why organisations that have embraced the Service or Web2.0 model like Technorati and Google run extended beta programs. The penny for me dropped when I read Steve Loughran's paper where he discusses extending the RUP to cater for deployment and operations use-cases - Steve's paper is also the first time I saw the notions of actually integrating on the live servers and letting developers access those servers in print.

In short: services don't get finished, they become available, and then need to stay available.

The next innovation needed in IT is not for new technology stacks, or new architectures, or even making techies and suits communicate. It's to find business models which support ongoing incremental development and deployment approaches implied by Service Oriented and Web2.0 approaches. To build better information systems, we need better financial models. The current fixed-price and time-and-materials poles apportion risk poorly. As a result they force parties into contract-heavy engagements, where sign-off to build can't occur before all the the requirements are known in advance. They result in high-ceremony processes that can trace all the requirements no matter how trivial and provide accountability no matter how incidental. Wanting to know the requirements is of course important, but insisting to know all of them is unrealistic, and not a workable approach anymore. There needs to be a means to support variability in projects - as Mary Poppendieck put it, every late requirement represents a stategic opportunity for the business if it can be delivered. Granted, the suggestion that the business models need an upgrade may sound unrealistic, but there's not much point talking about software as services or process agility in the context of rigid commercial frameworks.

Stefan's closing advice is this:

"From my experience, the best way to approach this is with a mix of high-level vision, introduced top-down, and bottom-up, quick win-scenarios that sort of grow toward each other: 1. Set up some initial guidance and high-level strategy, spending no more than a week on it. 2. Solve the next few small integration or B2B connection problems using 'SOA technology'. 3. Revise your high-level strategy to reflect what you've leaned. 4. Rinse and repeat."

My experience concurs with this. When the business people and the architects are thrashing out the documents and processes (which can take years or simply be an ongoing conversation that produces a stream of requirements), you cannot have the programmers sitting on their hands - they need to build something and show it to the business, so the business can ratify and refine what it's asking for. A culture of continuous deployment and tending to front line services will also help the organisation infrastructure become robust to continuous requirements changes.

[1] Subscribed. I'm delighted this man is weblogging. The J2EE patterns book is wonderful.

[2] Probably true for any software design approach, not just SOA. Grady Booch made the observation for about big systems being built from smaller working systems many years ago.

[3] The term for this in the Web Services world is 'protocol neutrality', but you also see in architectures like JXTA or FIPA.

[4] Decentralisation will come to be the norm for business systems over time which is one reason why developing an understanding of how Internet protocols and formats work is becoming a core skill, just as distribution has been a core skill in the past. Understanding Internet architectures and protocols is particularly valuable for appreciating minimal agreements and the importance of connectors.

Object, know thyself

Herb Sutter is at the message-passing party:

"Shared state is evil (for concurrency, but also for so many other reasons including plain old single-threaded coupling). Async messages are the way to communicate."

He goes on to say:

"Point solutions already exist for all of these things, but they now need to be brought into mainstream programming languages in a usable and accessible way. And that's what I call the "OO of concurrency" - those extensions will be as much of an extension as classes and virtual functions. Ada95 and Java do some of it (but not nearly enough), ditto for research languages like QC++, and ditto for OpenMP (which I view as industrial-strength duct tape, strong but an ugly band-aid) - all of those are more similar than they are different, and incremental steps that basically stick with the current status quo (in particular, supporting shared state and locking), which is fundamentally not good enough. [...]. Functional languages have long been well-suited to concurrency, but likewise I doubt that mainstream programmers will make a functional language the dominant commercial programming language anytime soon; it's too different from the imperative model.
So there's a lot of interesting research and directions, exploring useful avenues, but we need something a lot smoother, cleaner, and applicable to current imperative programming languages. I and other people are actively working on that."

If message passing and state isolation is that important at the programming level [1], then by the time you're done patching C++ VTables, or waiting for Java to have Isolates, or waiting for Windows to have Indigo, arguably you might as well have shipped it with E, Erlang [2] or Smalltalk. And as far as I can tell, using a message passing language could be just as big a jump for Joe Dev as using a functional one - having weird syntax while not having assignments is one thing, having your head turned inside out about synchronicity and state is another. That said, I can't wait to see what he comes up with on the language/tools front.

[1] as opposed to the XML-contracty stuff we see in REST/WS/SOA

[2] Real world, can do.

March 19, 2005

random 10

  • [Crumbs From Your Table - U2]
  • [Coldplay - Shiver]
  • [Diamond Dogs - David Bowie]
  • [Lemon - U2 (Pefecto)]
  • [A Little Less Conversation - Elvis Presley]
  • [You Stole The Sun From My Heart - Manic Street Preachers]
  • [Early Morning Rain - Eva Cassidy ]
  • [I want more - Faithless]
  • [Boobytrapping - David Holmes]
  • [Run, Baby, Run - Sheryl Crow]

March 18, 2005

New slide for Sam Ruby

Here you go:

only registers with the unicode

This would not register with any other string... details took a trip through HTML forms, email response and finally the app textbox. So near, yet so far.

WikiSpam, TruckNumber, AnonymousCoward, LinkLove, LinkSpam

C2 is the finest repository of programming lore on the planet. But it seems Ward Cunningham is having severe spam problems over there:

"Due to continued abuse by vandals and computer programs we now require the entry of a random code word before we will save changes to pages. The current codeword will be made available on the edit page at times when I can directly supervise the site." - WardCunningham

It's not good that Ward has to be onsite to do this - as Steve Loughran pointed out "How can you be a wiki, when you don't allow edits?". But Ward's already sorting out the Wiki's TruckNumber - "I am assembling a group of stewards who have both a financial and emotional stake in the continued health of this site.". He has a great instinct for the social aspects of creating and using software; it will be interesting to see what he comes up with here.

In the meantime the Perl script that runs Wiki could do with an upgrade. An image captcha would help for now as would a javascript munged math question insofar as they make automated attacks difficult - they won't work so well for manual spammers.

I think, for the Atom crowd, this also indicates a limitation of using IP addresses either as identifiers or means of outing people (be they spamming or astroturfing). If the incentives are sufficient, embarrassment by IP is not a deterrent.

The core problems here are threefold:

  • Anonymity: people are making money in an anti-social fashion from link spam without having to reveal themselves.
  • An absence of deterrents for spammers: if I can make money spamming in an anti-social fashion, without the problem of the people's who's sites I'm wrecking knowing who I am, and without breaking any laws, why would I stop? So then we have to ask, on a public wiki or weblog, is registration really a problem?
  • Search engines: the point of link spam is typically to game search engine rankings. The idea of downloading the web into a database for indexing has always been a questionable idea, even more so now that it seems the statistically based ones have sufficient difficulty dealing with spam and blog topologies, that their inventors want us to pepper our blogs with metadata.

Technology alone can't deal with a problem that's mainly socio-economic in nature - only the last item in that list is really to do with technology or systems design, and arguably solving it for the current search architectures is AI-hard. Anyone who still believes Bayesian filters will win this war is blithe to how dynamic systems with limited resources and competing actors work, plus the fact is that the end-goal for online spam is somewhat different to email spam in ways that make Bayesian techniques less effective.

Search engines as of 2005 are incapable of telling the difference between link-spam and link-love - it's all whuffie to them.

March 17, 2005

Trust and Robust

If you are using schemata to validate incoming XML it means you either do not entirely trust the sources of the XML, or your system is not going to be robust to unexpected data forms. Or both.

So, take a look at the use of schemata across your systems; they mark boundaries for trust and robustness.

March 16, 2005


"Google never did any advertising. They're like dealers; they sell the stuff, but they know better than to use it themselves." - Paul Graham

Coyote: Jython and Groovy on NetBeans

Sun announce Jython and Groovy support for NetBeans 4- Coyote. Cool.

[Via Sean]

March 14, 2005

1060Research NetKernel review

Carlos has a short review up of 1060Research's NetKernel. I really need to take that system apart some weekend.

Hmm. Upgrades.

Having failed before, I seem to have got Zempt working this evening along with the WMPtunelog plugin for iTunes (nearly working anyway, Zempt's complaining it can't file a file on exit). I also bought a copy of FeedDemon which integrates with Zempt. Aside from the (very) neat UI, it rips through my feed list (which is now in the hundreds). Plus it supports enclosures for iTunes and bloglines. It'll be interesting to see if the tools affect the weblog entries - I tend to write long entries. It's a bit grim to do that through a letterbox form online; they also tend to have lots of typos on first publication.

In work we're going to move to Subversion 1.1.3 to avail of the flat file system. We've had a couple of incidents of Berkeley db getting wedged in the last few weeks after increasing our backup cycle frequency.

On the hardware front, a new laptop is soon come. The Dell I turned off for an hour today after I started to smell warm plastic - it's an Inspiron 8500 which has always run really hot (as in I've-burnt-my-fingers-on-it-hot), but I think it's doomed despite getting a new motherboard a few months ago. A mass backup to an icy-box has been done.

[Forget Me Knots - Roni Size - Touching Down]

Jabber needs to die so XMPP can live

I don't know, the proprietary IM folks must think it's 1994 :) Ted Leung is right, XMPP is the way to go. Anyway, I'm up to here with having 3 different IM handles when we all could just roll out Jabber XMPP and be done with it [1].

One problem with XMPP is the community can't seem to get out from under the Jabber legacy.

The way to deal with that is somewhat brutal - shut down jabber.org - forever. And then go on a branding spree - start by renaming the J SF the XSF. And start calling JEPs XEPs. Perform a ruthless, internet-wide search/replace operation until Jabber has faded from memory, gone the way of WAIS and Gopher.

Speaking of JEPs. if WS has a spec overload problem, then going by the current spec list arguably so does XMPP. People need to stop writing JEPs, for about 3 years, so we all can catch up and do the mundane stuff like harden servers, write conformance suites, discover the working subsets, hammer out interop, fix bugs, figure out which JEPs matter and so on.

So, here it is - no more JEPs after St Patrick's Day ;) Maintain the moritorium until 2008. Which by then will be called XEPs.

[1] For Java folks OpenIM works just fine and the Smack client libs are easy to use. Ejabberd however is arguably the most robust open source XMPP server out there. Don't let the Erlang codebase put you off, ejabberd's a piece of work, and highly active. It does however, need to be renamed :) Anyway, think of it - here's your chance to glimpse the future by hacking some Erlang.

HTTPLR draft-01 published. Some background. Some futures.

HTTPLR is an application protocol for reliable messaging using HTTP. The protocol specifies reliable delivery for upload and download of messages. A new revision, draft-httplr-01 is now available and supersedes draft-httplr-00.

Feedback on httplr-draft-00

I've had great comments and observations so far, which has fed directly into the 01 draft. A big big thank-you to everyone that took some time to comment.

To be honest I wasn't sure what to expect - deafening silence came to mind, and maybe some heat from WS and REST advocates, but so far it's been positive [1] and quite insightful. There were some thinkos and things I had straight-out missed in draft-00 that were graciously pointed out and I think draft-01 is a better document as a result of that.

Some people asked about code - there will be an RI (see the Roadmap below). As far as 'does it work?' goes, the answer is yes. I've mentioned before that an earlier draft of the upload protocol has been running in production for over a year - the essential protocol logic is the same but the public versions are more detailed with respect to things like headers and status codes. In work, we're currently implementing the download protocol.

Changes from draft-00

The revision history is in the spec, but I'll pull out the highlights here:

  • 8: Removed Allow: from "Sending a message to the exchange URL" figure (Allow only applies to the created exchange URL when PUT is used to create the resource).
  • 8.2: Clarified PUT/POST/DELETE negotiation/interoperation for message delivery
  • 8.2.1: Moved to 8.3 (as a special case)
  • 8.2: Changed response code for informing a client the message has been reconciled from 405 to 410
  • 8.2: Highlighted Behaviour where PUT delivery is not supported (as section 8.2.1)
  • 8.2: Highlighted Behaviour where delivery is repeated (as section 8.2.2)
  • 8.2: Added DELETE to list of allowed methods in figure 2
  • 8.3: Highlighted Behaviour where DELETE reconciliation is not supported (as section 8.3.1)
  • 8.3: Highlighted Behaviour for Rejection of out of order DELETE requests (as section 8.3.2)
  • 8.3: Use 410 Gone to repsond to repeated reconciliation requests
  • 9.1: Changed example to use atom05
  • 9.2.1: moved to 9.3 (as a special case)
  • 9.3: Removed inconsistent text around client behaviour when sending repeat reconciliations.
  • 10: Clarified dictionary attack as pertaining to both digest and basic auth.
  • A: added 501 to the list of status codes.

Backgrounder and design notes

Some people have asked me about the design rationale and background of the spec. I'll take a stab at that here.


I suspect that reliable-over-HTTP has a longer history than I'm aware of, but has been one of those things that no-one bothered to write down. I would guess the basic 2-step send and reconcile model has been around for years, possibly going back to the Nineties. With the possible exception of trying to stay within the confines of HTTP (no URI deconstruction, no peeking in message bodies) HTTPLR isn't all that innovative, and is in one sense merely documentation.

I've been working on reliable HTTP in one form or another since early 2002, which is when reliable messaging over HTTP started to pique my interest. In 2001 in the UK, I started to see scenarios under which failed content delivery unbeknownst to the client could cause problems.

It was Paul Prescod's Reliable delivery in HTTP that initially inspired me to write the process down formally and that was cemented by some experiences during my time so far with Propylon. The earliest articulation of a HTTPLR protocol document dates from 2002 and the IETF style document started in summer of 2003. The protocol had gone through several revisions and implementation experience before releasing draft-00. There's even a document on the web dating from August 2003, but I never linked to it as I didn't think it was baked enough at the time (whereas at around the same time something like "Click Submit Only Once" was).

At Propylon I had direct exposure to problem spaces where documents had to arrive once and only once, and eventually that resulted in an opportunity along with Praveg Arkadi (a colleague) in late 2003 to implement a solution against an early draft of the protocol. Two senior work colleagues, Sean McGrath and Conor O'Reilly, had also been looking at messaging along much broader perspectives for eGovernment; that was influential in us taking a protocol oriented approach.

Paul in his document claimed it was so simple it was hardly worth bothering with from a protocol perspective, and if he were bothered he would use a new verb. I think he's right that is at heart, simple, but wrong that a new verb is the way to go, purely for traction purposes (technically I have no argument against new HTTP verbs). IBM's HTTPR had new verbs and I think failed to catch fire in large part due to that (although there is other incidental complexity in that spec that prevented adoption). WebDAV created new verbs, and despite being really useful and extremely well thought-out, continues to have a slow (but steady) adoption rate - that alone should give anyone pause about verb proliferation on the Web. But if that's not enough, HTTP itself has had problems - the deployment reality is that GET|POST is what most people are working to.

So, if you are after adoption on the Web, you will tend to avoid creating new verbs [2]. The problem is that the restricted verb set complicates the protocol and makes implementors go through more hoops that is strictly necessary (more on this below).

Why Client/Server? Why HTTP?

Most WS RM specifications are what an early version of HTTPLR termed 'heavyweight'. They all assume both parties have a web server exposed and function by correlating IDs between pairs of clients and servers. In principle there's nothing wrong with this and you can build high-throughput systems by emulating full duplex with a pair of HTTP connections (which is why I don't use the potentially pejorative 'heavyweight' anymore). I have a good bit of experience for example with the BizTalk Server series which uses connection pairs in this way and it's a perfectly fine way to realize reliable messaging.

In more restricted scenarios however, replacing a HTTP client with a Server in a DMZ and doing the consequent integration to the backend is not always an option - some users just need to send messages and don't want to invest a lot of infrastructure in having a server just for that purpose. Having a 'half-duplex' client that (in theory) they can run from a desktop is an attractive proposition. Aside from system integrations, there are also consumer-oriented scenarios where reliability using pairs of servers isn't an option, but client/server is (J2ME mobile devices come to mind).

Why HTTP? Because it's there.


Much of the feedback I've had so far has been around the choice of verbs. Opinions conflicted on this. Some people thought that POST was noise - use PUT|DELETE. Some people thought PUT|DELETE was non-interoperable - use POST.

I'm not surprised about this - one of the reasons HTTPLR has a long history is because of this tension between the HTTP as specified and HTTP as deployed. Clearly PUT and DELETE are the right choices for specific operations. But the fact is that most of deployed web is configured for GET|POST. The best thing to do after a lot of thought is to keep as many options open as possible and that means allowing users to choose PUT or POST, DELETE or POST.

Feedback on draft-00 has helped clarify a means of interoperation amongst the options [3]. Nonetheless I'm not happy about it. It adds complexity to the spec and to implementations.

The main technical problem with using sequential POSTS is that you need something else to switch on to figure out what state in the exchange you're in, in case you need to right yourself (what Paul Prescod dubbed a "confused client"). This doesn't matter too much for a person working the state machine via forms, but it sucks for automated clients. Figuring out a control code to switch on that isn't in a URI or in a served representations requires a lot of fiddling with response codes and headers. HTTPLR is choc-full of it.

The beauty of PUT|DELETE or GET|DELETE is that you can use the methods as the control set. Both the specification and code for state transitions in HTTPLR gets a lot simpler. The problem is that PUT|DELETE deployment is sketchy, so you're automatically excluding a swathe of people from using HTTPLR aware toolkits, be they using J2ME enabled phones, or Apache servers with no administration options.

[In the Web protocol space, I believe Joe Gregorio is due a lot of credit for popularizing verb transitions and demonstrating them as a workable idiom. I also think he has much the same feelings as I do about the current state of affairs with GET|POST.]

How did we get here? That's easy - HTML forms. Be in no doubt, the subsetting of HTTP by the W3C in its HTML specs is a bad design decision that has affected consequent REST and WS efforts. XForms redresses this situation, but without DELETE (I don't know why). It bothers me that the W3C TAG can agonize over http-range-14, but hasn't yet (to my knowledge) considered the consequences of HTML subsetting HTTP by design - HTML still being the premier format on the Web.

MEST and processThis() [4] advocates should read HTTPLR just to see what happens when you don't provide sufficient verbs to communicate. The MEST approach seems to favour an adverb/adjective approach to communications and is being well thought out - I think they will deal with this by constraining the content model beyond SOAP. Mark Baker's explorations with RDF Forms are another approach to constrained content. Anyway, I reckon ~30% of the protocol document is given over to dealing with GET|POST reality - in other words a lot of verbiage and conditional complexity could be removed from HTTPLR given two more verbs. In my experience ~30% is also roughly the code blowup that will result when you have insufficient verbs to work with. The operations have to go somewhere and the empirical evidence is that CRUD represents a useful minimal verb set unless all what you want to do is grunt rather than speak. That or you could wind up with two protocols interacting across architectural layers.

[By the way, with HTTPLR, URLs are under the server's control and no URIs are being created via PUT requests. But, we are left with tunneling PUT|DELETE over POST nonetheless. That's not a good situation. If I sound annoyed about this, well, I am.]



I expect the spec to go through a few iterations this year. I haven't put it on any kind of release cycle yet, but I reckon the next draft will appear no earlier than June 2005 with maybe two more drafts before the end of the year.

The long term intent is that it end up in the IETF, but I would like to have running code in the wild before that.

Source code

There will be a reference implementation (RI) of HTTPLR, client and server libraries. The server RI will be Servlets/Jython with plugin persistence support for ActiveMQ, Joram and MySQL backends. The client RI will be Python, but I would like to see .NET client as well.

The main thing holding back an RI is, as ever, finding the time to get code out the door. Other niggly things that are holding me back are public hosting (I want Subversion, not CVS, so Sourceforge is out) and choice of licence - LGPL v ASF (I'm leaning towards ASF at this point).

If you are thinking about implementing the spec, that would be cool. Ping me about it.

Relationship to WS

Just in case anyone thinks that HTTPLR is meant to be a counter-proposal or a foil to the various WS reliable messaging specs, it's not. It's only meant to be a guide for doing something specific with HTTP as deployed, that HTTP does not provide for "out of the doc".

The WS RM specs are fine by me, the problem is there's too many of them. I for one would like to see the industry coalesce around one spec and have that available in as many stacks as possible [5].

I think it's good to have a raw HTTP protocol option especially for scenarios where pairs of servers aren't an option. And I see that Tim Bray says this area is important. You know, he's as good an arrow shooter as any :)

[1] Robert Sayre even had an exclamation mark in his blog entry, so I guess he must have liked it ;)

[2] In time this might be not true, the signs are that people are waking up the GET/POST situation. But I think it will be years before the full HTTP+WebDAV are ubiquitous.

[3] Sean McGrath, my CTO, has reminded me many times that optionality can be a curse. I believe Sam Ruby holds a similar, hard-earned, viewpoint.

[4] I'm prone to calling processThis() 'NOOP' - it helps me remember where the real action is at ;) Jim Webber, it turns out, is a Thoughtworker - that's news to me (those guys are everywhere).

[5] Increasingly this looks like WS-ReliableMessaging.

March 12, 2005

How long would it take to move Mount Fuji?

Dabid Megginson is ruminating on XML Namespaces, and concludes:

"It's too late to change Namespaces now"

I'm more upbeat that things can be changed once we know better. In XML Namespaces, default namespaces and attribute scoping are something of a problem in the trenches. Addressing them is not going to be a case of meddling with the infrastructure so as to reap no benefits. I imagine they cost the industry no small amount (just think how many developer-hours have been expended on SAX2 namespace processing alone).

How would we go about changing something when it's too late to change? There's no quick fix, no magic bullet, but there are 3 things that come to mind:

  • Stop the rot. Call out what has gone on before as an anti-pattern. Indicate that no technology will be executed in that manner in future. Have zero tolerance. One of the issues with XML today is that while there are conversations about the merits of various parts of the puzzle going on within the XML world, there's a lack of ruthlessness in clearly stating what people should not be doing across the industry. It might have been risky to do this 4 or even 2 years ago, but XML is so well-established now, actively identifying, cataloguing and eradicating anti-patterns does not put its continued adoption at risk. Quite the opposite.
  • Establish what should be done instead. Define the best practice and evangelise it. For example with namespaces, this might be to always use prefixes or to always have acceptance criteria that your markup be easily and soundly embeddable in other markup. Elliotte Harold's Effective XML is a good place to start as are the IETF guidelines, and both need to be continually updated. The Reach RIG documents are also valuable guidelines, as much for the explicitly articulated process of evolution through subsetting as the technical specifics.
  • Clean up your legacy. I take my cue from the agile mode of thought here. When you are surrounding by broken windows, and being surrounded by broken windows is costing you, you fix them one at a time until you are done, or until you have fixed enough windows that there are no more broken ones being added. On the face of it such work often seems impossible (hence the title of this entry being "How long would it take to move Mount Fuji?"), but that's only if you take it as one big job to be done. Software after the fact is long lived, and most programming is maintainence programming - but you will have to apply triage as to what parts to fix nonetheless.

To be clear on this, no-one should expect that the writers of a specification can see all eventualities and consequences of their work. So when I say there's a problem, it's not apparent to me that anyone could have forseen back in 1998 or earlier, that a dominant use of XML would be as an enveloping and packaging technology for messages and protocols, which is where these issues tend to bite hardest. One way to obsolete a software technology is to suggest it cannot evolve. So on the balance, I think it's worth keeping the option to change XML+Namespaces open.

In short, never say never - things can always be made better. XML+Namespaces as of 2005 is a local maxima not a frozen accident.


Here's some podcasts I seem to keep coming back to:

March 10, 2005

Thinking bad, Foostering* good

Via Patrick:

"SQL, Lisp, and Haskell are the only programming languages that I've seen where one spends more time thinking than typing." -Philip Greenspun

Patrick has more:

"There are some others to add to the list: Smalltalk, Python, Ruby, SML" -Patrick Logan

For a more surreal take on the dangers of surplus thinking time, see Programmers Block.

* Foostering

March 08, 2005

Frameworks are leading indicators for programming languages

Patrick has a dig at Rails. Hype deflation is a good thing (and RoR is over-hyped), but one thing he said in comments bothered me - that programming languages don't matter, at least not with respect to frameworks and tools.

First of all, I want good languages, frameworks and tools - these are not mutually exclusive. Second, programming languages clearly do matter. For example the capability of the base language will heavily influence the requirements for any framework you build on top of it and the particular software patterns and idioms you need to use. You write enough C code and you end up wanting a VTable; you write enough C++ code you end wanting garbage collection; you write enough Java code you end up wanting funargs. Each time, someone will build a framework or a library to support something that will end being part proper of another language. A framework is a patch for a programming language.

A framework is also a way of dealing with impedence between a programming language and its environment - in particular with respect to how data is modelled. For example, the plethora of Java web frameworks probably comes down to a mismatch between object oriented languages and web architecture - this, in much the same way objects mismatch with relations or XML, but there is better awareness in the Java world about those two.

Frameworks provide leading indicators of what developers want to get their work done. The signs with Java frameworks indicate developers want for support for function passing, easy introspection, inverted dependency management, and object runtimes that are essentially REPLs.

Finally, Patrick says he plans to a better job of promoting OpenSymphony. No argument there - OpenSymphony is consistently one of the best Java OSS foundries. WebWork, Quartz Sitemesh, and OSCache are all excellent.

March 02, 2005

Communication Languages

Mark Nottingham is noodling on data models

If you're the only person who every has to look at the XML or write software to work with it, youre fine, because you'll say exactly what you mean (no more, no less). When you start involving other people, however, things get complex pretty quickly.

That's because you have to agree on whats being said, and just as importantly, what isn't. What's that attribute? Is the ordering of the children of that element significant? What's the relationship between 'item' and 'entry'? And so forth.

In a nutshell, I see this problem as one of choosing a data model along with an appropriate constraint (i.e., schema) language, and then figuring out how to get from that data model to angle brackets. Therefore, I present a choose-your-own-adventure guide to using XML in data-oriented formats, with the pros and cons of each choice.

Mark gives 2.5 options

  • 1. Your data model is based on XML: "This path is, in my opinion, the major reason behind the wailing that we hear when people actually try to use Web services and XML (lots of people seem to agree). It isn't pretty, and I don't see it easing significantly, despite the advent of better bindings of XML into languages, or better schema languages. I suspect that Infoset-as-metamodel is the root of the problem."
  • 2a. Static, fixed mapping from that data model to XML: "Basically, these approaches are using XML as a serialisation format, in the sense that they're using it to mindlessly serialise an object or other model into XML. The integration into the XML stack is almost accidental where it happens, and for these reasons, I don't think this is much of an option."
  • 2b. An application-specific mapping from that data model to XML: "many XML-based specifications are actually described in a separate data model, even if it's just a set of XPath expressions. Disconnecting from the constraints of the Infoset frees you to think about what the data model should be, not what it should look like in bits."

Option 3 would be to focus on the application protocols rather than the content models of the payloads. That would mean new methods and header metadata or possibly a tad more formalism than the current processThis() (MEST) or HTTP POST (REST) styles. Certainly you'd be starting with a set of well defined communication primitives than could be re-combined or extended rather than providing a bucket method for any semantic that the the protocol designers did not forsee or a method free for all.

You can think of it this way - if Lisp and Smalltalk represent some kind of maxima for expressivity in programming languages then speech act languages like KIF and FIPA-ACL represent a maxima for expressivity in Internet application protocols. Enough research and experimentation has been conducted on software agent communication languages over the last twenty years to gives us an inkling of how this might work. The primary problem with this option is social - my guess is that it's more difficult to innovate with application protocols than content models since app protocols tend to be baked into the infrastructure as of the beginning of the 21st Century. And we do tend to think of protocols in engineering terms (interfaces, structures. bits, wires) rather than as linguistic phenomena. It's not called the Internet Language Task Force after all.

Given the circumstances, one hack then, would be to tunnel an extensible protocol language through the popular deployed protocols in way that was consistent with the protocols' performatives. RDF is not that language but could serve as some kind of Linear B for a more evolved protocol language. The concept of protocol neutrality in WS remains misguided as do bucket methods in app protocols.

Instructions per byte

"The Internet is not a CPU backbone.

So here's the algorithm. If the instruction density, that is the number of instructions you execute per byte of network traffic, the CPU time per byte of network traffic - if it's greater than 100.000 - ship it. And if the CPU at the other end is free, then it's a positive ROI. If you have less than 100,000 instructions per byte, it's a negative ROI.

So, most of the people I work with, Renderman, is a little under 100k per byte, ray tracing kind of things. Astronomers I work with, they're looking for galaxies, doing point spread functions and doing curve fitting, and basically doing vision on pixels - they're at the 10,000 instructions per byte density. And MPI, if you at it, is way way down on the instructions per byte, which is to say 1,000 instructions per byte, 10,000 instructions per byte for a typical MPI program.

Fundamentally this is a way of saying, if you have a computation, when should you do it in the cluster and when should you try and ship it out into the wider Internet, and the answer is this. Now of course, this algorithm and this equation changes depending of the cost of processing and the cost of network."
        - Jim Gray, Distributed Computing Economics

March 01, 2005

Hibernate 3.0 released

Gavin King announces Hibernate 3.0

[note to self: upgrade!]