Why Javaspaces are not for me

In 2001/2002 I worked for 18 months at the now defunct UK Javaspace vendor Intamission, building their Javaspace implementation Autevo, which went on to  … er… “inspire” the open source Blitz product , released by Intamission co-founder & lead programmer Dan Creswell after he left the company.

One of the less satisfying aspects of that project was that, as I worked with Javaspace/Tuplespace -based systems, I came to believe in them less and less. I now believe that while Javaspaces have some great qualities, they also have some serious flaws. Here’s a brief outline of what I think these flaws are.

Some background for the layman

Javaspaces pride themselves on having a simple API based on 4 methods

  • write puts an object into the shared distributed space
  • read returns a copy of one object matching some provided query criteria. There are blocking and polling variants.
  • take returns a copy of one object matching some provided query criteria and removes it from the space. There are blocking and polling variants.
  • notify registers interest in being notified should an object enter the space matching the provided criteria.

Javaspaces use a Query by Example mechanism to query the state of the space. One presents an template Entry to the space, with zero or more public, non-primitive, serializable fields, any of which may be null, and the space matches any Entry in the space whose fields are equals() to the template’s field, while treating null fields of the Entry as wildcards that match anything. Thinking of Entry as being a tuple is a good analogy.

I subscribe to the design aesthetic as simple as possible, but no simpler. Unfortunately,  the Javaspace query mechanism is too simplistic, and not sufficiently powerful to solve practical distributed systems problems with:

No Range Queries

The query API allows one to specify either an exact value, or any value, but nothing in between. You can say “a Person of Age == 25”, or “a Person of any Age”, but not “a Person of Age 25- 34”. This is a result of Javaspace’s fixation with a flawed query-by-example model. As you might imagine, this limitation quickly becomes problematic when you try to build real applications.

Use of Null as Wildcard

Another nasty side-effect of the query-by-example model is that null becomes overloaded as a wildcard value. Accordingly, Entry fields cannot be primitive, and may not be null for any legitimate application purpose.

Lack of a readAll Operation

readAll would be the Javaspace analog of a SQL Select statement; ie find me all Entries in the space matching the provided criteria. Sorry, no can do. A Javaspace can give you one of them, but not all of them.

So for example, if we want to ask our space-based application, “How many tasks are in the queue?” , it can only reply “All I can tell you is that there is at least one.”

The Future

Someone should combine the best ideas from Javaspaces – a focus on high-performance, short-term storage of self-contained objects/messages, leases, and event notification, with a decent, extensible query mechanism. Now that would fly. (Maybe someone already has? … I havent been following this field closely in recent years)

Deleting from the Heroes of Arcadia domain: a thorny problem

Deleting Objects from a Domain Model in a safe and scalable way with minimal adverse effects, is a thorny problem.

Eric Evans Domain Driven Design book has the best discussion Ive read under the section on Aggregates, but its not comprehensive.

Im struggling to find a really nice solution in Heroes of Arcadia. My best shot so far involves a mixed approach – cleaning out as many root refs as I can, plus stamping the deleted object as inactive. An example:

Units can be removed from a Zone.

There are two primary references to a Unit, via its Faction and its Location. These are bi-directional. When a unit is removed, it notifies its Faction and Location that it is going and they remove their ref to it. As these are the primary indices, cleaning them out will prevent the creation of new refs to the removed unit.

Units may also be referenced from other domain entities uni directionally (meaning they are unaware they’re referenced), for example, by being the target of a spell effect. These refs will remain after the unit is “removed”. The unit must stamp itself as being removed/inactive, and all domain operations need to tolerate this state. Gradually, the removed unit should “drain out” of the system as refs expire.