I’ve been working a lot on a mailing list.
A list has an email address, a user has an email address, a user can subscribe to a mailing list.
A subscribed user can email to that list, and all subscribers will get that email.
To subscribe, you give your email address, you receive a confirmation email, you click on the link to confirm.
Same to unsubscribe.
Well it’s been a voyage of discovery 🙂
So it’s CGIs in Python with an SQL database for the back-end. No need for anything more than this – this is a simple, lightweight mailing list. We’re not talking ongoing background processes here.
Obviously, I used a state machine to control the flow of execution, and on an impulse I decided to try implementing the state machine in the database – which is to say, there’s a table of states, of events, and the state -> event -> state combinations.
I then after some time realised I would need to implement my usual approach to error handling – Python just throws a wobbly when something goes wrong, and actually want to build up a sane and user-readable call stack and ensure I always emit something sane to the HTTP server (otherwise it just thinks the CGI has fallen over and prints a 5xx).
Having done all this, what I’ve realised is that I’ve not thought properly about what happens when the database goes down.
The state machine steps through states (no kidding right) and there are resting states (like subscribed, or waiting for a confirmation link to be clicked on) and there are sequences of states, where you start the sequence and it moves through a sequence of states (which states depends on the outcomes of each state) and then reaches a resting state.
So what happens if the database dies during a sequence of states?
Well, what has to happen is *something picks up where we stopped*.
Uh. Ain’t nothing doing that… all the scripts are CGIs, they run when the user makes them run.
So really we need something like a background task which applies the state machine as necessary to every email address subscribed to every list.
…but in fact, all this state machine checking, you know why you need it? it’s for and only for handling the subscription and unsubscription work – sending out the email asking for confirmation.
So, those confirmations – they are good practise. In fact, on a list with any significant readership, they are necessary, to prevent abuse.
But are they necessary, *now*, for my list? my tiny list?
Not at all.
I could just have a subscribe / unsubscribe button, which directly issues the necessary single-statement SQL.
So in fact what we have here is an example – which has cost me many days of work – of writing *unnecessary code*.
This is in fact one of the key problems of software engineering – making sure you only write that which is *actually needed*.