Monday, July 16, 2007

On Handling Dependent Resources - The Ensure/Create/Test Pattern

Recently, I had to restructure some resource handling code. The case that I had some resources A, B, C, ... and each one depended on some other in order either to be created or to function properly. So I had to devise a way to handle the dependencies and make sure that whenever I used a resource, all its dependencies are met.

I will use a simplistic example to make things clearer. Let's say we have resource A, which depends on resource B, which in turn depends on resource C. A is created using B and B is created using C. Our code always uses A directly, so we need to make sure that B and C have been created before using A.

My second approach to the solution is a lazy, bottom-up one. Before using A, I need to ensure that it is functioning correctly and of course lazily create it at some point. Also, I assume that we can always have some test functionality to make sure that A is "alive". For example, for a DB connection we can always issue some test SQL statement (select 1 from dual is common among Oracle developers). In the previous statements, please notice my italics on the three notions: ensure, create, test. So here are my findings:

Client code that uses A:

ensure(A)
...do something with A...

The backbone routines:

def ensure(A):
if A is null:
create(A)
test(A)

def create(A):
dispose(A)
ensure(B)
B.create(A)

def test(A):
...

Notice that I am also using one more routine, namely dispose. Its role is to safely dispose a resource, meaning that it takes care that the resource is not null, it properly handles exceptions and so on. Of course, as you can understand, there are a lot more details for a production-ready code and the routines admit variations...Also, in the generic case, we may have a graph of dependencies...

This is how I came to the programming pattern, for which I just chose the name in the title. As I wrote above, this is my second approach. The first was a top-down one . But I am not going to give it here....