Skip to: Site menu | Main content

Gruple

Concurrent and parallel programming in Groovy

TuplespaceUsage Print

Tuplespace API Documentation

Spaces

In the tuplespace programming model, processes (or threads, in this case) share a memory space called a tuplespace. Gruple supports any number of named tuplespaces (or Spaces, for short), which you access through the Spaces object:

Tuples

The fundamental data unit, a tuple, is a Map (that is, an unordered set of named values). Once inserted into a Space, a Tuple becomes immutable. Immutability is an important characteristic of data in concurrent systems.

A sample tuple might be:

There are some restrictions on the types of values that can be used in a tuple. All values must either be:

  • immutable basic language types: Integer, Short, Long, Byte, Float, Double, BigInteger, !BigDecimal, Boolean, Character, String, or URI
  • Collections and Maps of these immutable values (to any depth)
  • User-defined types annotated as @Immutable
  • the "effectively immutable" type Date. (It is up to the programmer to treat Date as immutable.)

Arrays are not allowed as values in a tuple Map since there is no way to guarantee their immutability. Use an ArrayList instead.

Associative Access: Pattern Matching

An important feature of tuplespaces is that units of data are not matched by name or address, but by content. That is, a tuplespace is an associative store and the main method of querying is pattern-matching.

Specifically, you match a tuple using a "template" or "anti-tuple", which is identical in form to the tuple you're trying to match, but contains placeholders for none, some, or all values (technically, these are called "formals" or "formal fields".) In Gruple, a formal is typically represented by "null" (except when it's represented by a closure as illustrated below.)

Pattern matching example

Given a simple tuple such as:

all of these templates would match it:

Space Reference

To get a reference to a Space, use the Spaces object in one of these ways:

Operations

The basic operations that can be performed on a Space are:

  • put - insert a tuple into the space
  • get - read a tuple from the space (non-destructively)
  • take - take a tuple from the space (a destructive read)

Put

To insert a tuple into a space, use the put() operation:

This inserts the given tuple into the named space forever. The lifetime of the tuple can be controlled in two ways:

1. Specify the time-to-live in milliseconds

2. Use the !TimeCategory

You will see that all operations follow a similar pattern with respect to specifying times.

Get

As mentioned before, retrieving items from a space is done by pattern matching, so a get() operation requires a template as an argument.

To retrieve the tuple we inserted into the space in the put() example:

By default, a get() request will block until a match becomes available, i.e. potentially forever. The former example is equivalent to:

Just as with the put() operation, the default timeout can be changed in either of two ways:

The get() operation is non-destructive, so any returned tuple remains in the space to be retrieved again.

Take

The take() operation is identical to get() except that the retrieved tuple is removed from the space.

Transactions

Transactions are familiar to anyone who's done any database work, and they are supported by many tuplespaces including Gruple. This feature is very new and any difficulties/bug reports would be appreciated.

Usage

To create a transaction:

To use a transaction, just include it in your put, get, and take calls:

To rollback a transaction, use:

Semantics

The semantics of transactions are, I hope, what you would expect.

  1. A tuple taken from the space by a transaction can still be read by other transactions (or the null transaction), but cannot be taken by them. Once the transaction commits, no transaction can read the tuple.
  2. A tuple put into the space by a transaction is visible only to that transaction until it is committed.
  3. Tuples read (using get) by a transaction have no effect on visibility to other transactions

#1 might seem a bit odd. The idea being that until a transaction is committed, the space should look the same as always. However, allowing another transaction to take the tuple while the first transaction has not committed would cause a conflict.

Experimental Feature: Multi-space Transactions

Note that multiple spaces may participate in the same transaction. All they need is a reference to it. The usefulness of this feature is unproved and it has not yet been tested.

Further Reading

This brief usage article does not do justice to the power of tuplespaces or the variety of problems they can solve. The following is recommended reading for those wanting to know more:

Eric Freeman, Susanne Hupfer, and Ken Arnold. !JavaSpaces Principles, Patterns, and Practice, Addison Wesley, 1999.