Introduction

In which I endeavour to explain in a series of badly selected bullet points why you might have arrived at this page, what this collection of articles can do to make you a happier and more fulfilled person, and list my flimsy excuses for the choices of technologies you'll be exposed to as the development process unfolds.

Comments on this article can be found here at use.perl.org

(for the rest of the articles in this series, please see the table of contents)

What the repeated asterisk is a Vienna WoC TODO tracker anyway?

(if you want the canonical version of this or are convinced by the end of the first paragraph that I'm hallucinating, I would recommend that you read this page by the winter of code organisers themselves)

Well, once upon a time there was a group of insane camelistas[0] known as vienna.pm, who decided to prove their insanity to the world by hosting the 2007 stop of the dashes and sigils world tour, known also as Yet Another Perl Conference: Europe[1]. A fantastic job was done: Dates for the conference were chosen, speakers were found, selected and notified, and a veritable host of camelistas did descend on the fine city of Vienna[2] to enjoy a resounding keynote by Larry Wall, rapid and fluid registration, and a three-day smorgasbord of fine talks spread across three rooms well-equipped with modern and reliable projection and audio amplification equipment, punctuated by a fine and great feast at which copious quantites of good beer was consumed.

In the aftermath of this[3] it was discovered that the combined generosity of many individual camelistas and a small but august group of companies had left the vienna.pm with more than they could disperse - even unto the copenhagen.pm sub-cult which had made the error of volunteering for the same duty in 2008 - and found that should they not be able to find help in achieving a fuller dispersal they would be obligated to render up the greater part of the monies in tithe to the draconian monster Revenoo, a great and terrible magickal beast who haunts the land of Austria in which Vienna lies.

And so the vienna.pm did declare a Winter of Code wherein volunteers might tend to the needy and deserving among the projects of the perl world and be assured of a small financial token of recognition of their strenuous efforts for the cause, to ensure that they might continue to purchase bread[5] long enough to survive to reap the true rewards of their labour in worldwide fame and adoration.

As part of this great endeavour a system was developed, named the 'TODO test' system, wherein the caretakers of such projects might submit a description in word or code of a task that needs to be done but for which the supply of round tuits and other essential mechanical parts has so far been insufficient, that others better provisioned might step forward and complete the task, and in return receive a bounteous bounty on the confirmation of completion.

In order to avoid the abuse of such a system the guardians appointed by vienna.pm must of course watch carefully in oversight to ensure the quantities of sponsorship suggested for a test by its sponsor are of an appropriate magnitude and to verify that once the completion of such a task is known to have been achieved that the reward is released to the implementer of record.

Which would mean paperwork. And we all know how much geeks love paperwork. So of course some poor bugger had to be talked into automating it. And apparently that's me.

Why are you publishing this and why should I care?

A big part of why vienna.pm selected our[6] bid to write this application was that it has side benefits above and beyond a reasonable chance of resulting in some working code that will run the todo test operation. First, that the 1000 euro bounty offered for the writing of the application itself isn't going to come to me or to Shadowcat - instead it'll be added back to the pot to be used towards Catalyst and DBIx::Class related projects. Second, that the application itself is going to be developed using the new Reaction libraries which I and a small team of perl ninjas have been working on, and will be commited into the Reaction repository to serve as the first significant public example of its use. Ain't open source grand?

Given this is going to be Reaction's first public example application, it seemed like it would be a good idea[7] to try and put down my design and implementation process in public to complement the code, and hopefully to make it easier to understand why I made the choices I did, what the code is actually doing and how it does it. It should also, if I don't screw this up too much, provide a good starting point for people wanting to build their own applications using the same technologies and an insight into my personal development process. Whether this turns out to be as interesting as I hope will be proven one way or the other by the site statistics; we'll see.

What technologies are going to be used?

Well, obviously, perl. Lots and lots of perl. And as much of CPAN as I can possibly leverage to avoid writing code myself. More specifically, I'll be using the Catalyst web framework to power the HTTP interface and dispatching process, the DBIx::Class object-relational mapper to handle the database interface, and the Moose meta-object orientation syntax extensions library to provide a uniform introspectable object model and to save me writing unexciting things like accessors, constructors and type checking myself. I'll also be using all sorts of exciting extensions to these three that provide various extra chunks of functionality in a plug-in fashion, plus the Reaction libraries on top to tie everything together and handle the UI layout, composition, validation and workflow (more on what that means in the next section).

For a database backend, I'm planning to use the excellent open source database PostgreSQL, since it's powerful, scalable, comes closer to the appropriate standards than most available alternatives[8], and the psql command line client kicks the stuffing out of sqlite3 and mysql[9]. I'm probably not going to actually mention it very often though, because I'm going to use DBIx::Class' SQL::Translator integration to deploy and upgrade my schema for me so while we'll be looking at the table setup and data occasionally to see what's going on I won't be writing much SQL myself.

I'm not actually going to use a web server during most of the development process since Catalyst's standalone server is much quicker and easier to test against and when I get as far as skinning the app I'll be configuring it to use the POE HTTP engine which can prefork so that static files can be loaded by a separate process from the one serving the main request. For deployment I'm planning to provide init scripts for a standalone fastcgi daemon bound to a unix domain socket so the webserver becomes a moot point; I think vienna.pm are using apache so we'll be using the old workhorse mod_fastcgi which is my usual deployment platform, but more because I've spent a long time doing apache administration and am nicely familiar with its foibles than as any sort of endorsement.

Ok. But what the hell -is- Reaction?

Reaction is a set of libraries built on top of Catalyst and Moose designed to provide an application metamodel that allows rapid development of MVC applications with a two-layer model and a component-based UI.

The idea of the two-layer model is that the innermost layer of your application is a pure Domain Model, whose only purpose is to provide a representation in code of the business rules/logic of your application and to handle the persistence of the data involved. It allows the modification and management of this data, but can expect to be given correct data and as such if it isn't just throws an exception which the calling code is expected to deal with. In front of this sits an Interface Model (also referred to as the FacadeModel pattern), which provides not a user interface but a progammatic interface to the domain, designed to expose common queries and mutations of the domain in a clean fashion with a guaranteed interface that can be maintained even if the domain model needs to be altered later; the UI code is written against the Interface Model. Of course, there's no requirement for a one-one correspondence between UI app, IM and DM packages; an IM can easily talk to more than one DM to provide its functionality and a DM may accumulate several IM packages as time goes on and its purpose expands.

For simple cases where the IM/DM split is just extra boilterplate, Reaction provides code to reflect an Interface Model from its underlying Domain Model by introspecting available attributes and methods and generating out the additional layer automatically.

The component-based UI approach takes its inspiration from traditional GUI systems and from widget-based systems such as barracudamvc and wicket; it abstracts out UI processing into several layers. The ViewPort layer operates as a selector onto the model and receives user events to handle things like paging, sorting and searching of views onto the model and receive and validate form input and when permissible send the intended changes to the model to be applied; Reaction controller code generally instantiates a tree of viewport objects representing the current overall state of the current UI screen and then delegates the finer-grained processing to the viewports. In front of these sits the view layer, which observes the viewports to determine what needs to be rendered to the user, using LayoutSet objects (which define the visual rendering of the UI element via a set of small logic-free templates) backed by Widget objects (which define the rendering logic, pulling data from the viewport being rendered and massaging it appropriately to be used by the layouts and handling fine-grained rendering flow).

Reaction provides a large set of pre-built viewports, widgets and layouts which provide basic services such as a pageable, sortable grid and a general form handler which can be used out of the box and then selectively subclassed and overridden in order to meet the specific UI design and theming needs of the application.

If all this seems like overkill, I shall merely note that my experience is that any sufficiently large Catalyst codebase contains an ad-hoc, informally specified implementation of half of Reaction[10] and long exposure to CPAN has made me really sick of reinventing this particular set of wheels.

Are you going to shut up now?

Yes. Thanks for reading, there'll be actual design and technical stuff in the next part. Promise!

Comments on this article can be found here at use.perl.org

The next part is Database and Domain Design


[0] Camelista, n.: Member of an obscure sect that believe in the philosophies of TimToady, the poeticity of perl and the consumption of beer (this last part has been claimed to be optional but my travels to the sect meetings of such leave me unconvinced).

[1] Often shortened to YAPC::EU by those unlucky enough to live in countries where pre-glasnost character rationing usage was never lifted, and by those afflicted with chronic laziness of the fingers (i.e. perl programmers).

[2] Also known as Wien for reasons I am assured are entirely unrelated to the etymology of the word Berliner (although I forget by whom, alas).

[3] More precisely in the aftermath of the aftermath, which itself primarily consisted of the brave and virtuous members of the conference committee assuming a foetal position in the corners of various IRC channels and muttering "I am never organising a YAPC again" over and over while rocking backwards and forwards and humming softly[4].

[4] This is also a great and long-standing tradition of YAPCs.

[5] Although, alas, likely not circuses.

[6] Our in the sense that I represent not just myself but Shadowcat, which is kindly continuing to keep -me- in bread while I build this, and if the development process turns out to be more stressful than expected possibly also the financial interests of my local public house's landlady.

[7] Possibly much in the same sense as which it seemed like a good idea to vienna.pm to host a YAPC.

[8] To forestall my being shouted at by castaway (Jess Robinson), yes I know DB2 does better at this part. But installing it makes me want to gouge my eyes out with a rusty spoon and it isn't open source.

[9] For those of you unfamiliar with the idiom, that means I think it's better. Lots and lots better. And it's shorter to type, too!

[10] With apologies to lispers everywhere for quote abuse