Street Programming

The street finds its own uses for things. -- William Gibson

What street uses have been found for Tcl?

I was looking for a way to tie together two SMTP servers, both hungry for forwarding information that was coming in from a single source (an HTTP server on a separate box). Both had to have the information at the same time; a third SMTP server may be added later. If one box went down, the others would continue to function and receive forwarding information as it immediately became available. While trying to figure out a way to get this information (essentially a growing file of email accounts -- in cdb format for qmail) broadcast reliably to multiple machines (shall I push or pull?) it occurred to me that a Tuplespace would do the trick.

A quick refresher on Tuplespaces reminded me that it was a (usually) in memory data-store where 'everything' was a key. You put tuples there. Things like: { forward [email protected] [email protected] }. This is a tuple. You can put, read and 'take' (read+remove) tuples. You can search them by 'wildcarding' elements (e.g. { forward ? ? } would return any 3 element tuple that starts with the element 'forward'. Persistence of the data is an added benefit. You can use Tuplespaces for message passing. If your put/read/takes are atomic operations, you have the beginnings of transactional integrity. Heck, you can even specify (as a client) that you want to wait until a tuple becomes available.

So, the SMTP servers all wait (read_wait) for a tuple like {cdb data ?} to become available. The wildcard in this instance stands for all of the forwarded mail addresses. When a new forwarding address recorded is 'put' from the web server (put {cdb data xxxx}), all of the SMTP servers unblock, read the appropriate tuple and update their own cdb files.

What does this have to do with Tcl? Well, a properly implemented Tuplespace (as derived from Yale's original Lindaspace reference or even copped from JavaSpaces) would represent tuples as tuples (essentially lists). The street implementation in Tcl takes advantage of Tcl arrays. Each tuple is an index into a Tcl array called tspace. Advantage? Quick, cheap and if you use '*' for wildcarded elements (instead of '?'), you can use array names to do lookups. Toss in a trace on the array and you can use something like Metakit for easy persistence. You lose the tupleness of the Tuplespace concept ({1 2 *} would match {1 2 3} and {1 2 3 4} which are NOT similar tuples), but you retain the simple transaction friendly coordinations of put/read/take.

Is this really a Tuplespace? Strictly, no. But it's a street use of a Tuplespace.

-- Todd Coram

Sometimes you want to leave the streets for more refined territory. I've recently implemented a more elegant version of a Tuplespace in Python. But, there is no reason why Tcl can't get all gussed up too. Here is a simple Tuplespace in Tcl (sans any persistence or networking support). Not quite as pretty as Python, but adding networking support (go fileevent!) is where Tcl shows its real street savvy! -- Todd Coram