Here you will find a (hopefully growing) collection of patterns and blueprints for deployment and software architecture of systems based on JINI and JavaSpaces.
Coming soon: Advice on constructing simple resilient implementations
Update: 23/2/2004 Completed testing over the weekend. It works! I've submitted a presentation proposal for the Seventh JINI community meeting. Full implementation blueprint to follow soon.
Update: 17/6/2004 Presentation slides are here.
notify() and wanting to be
able to obtain the associated entry.As mentioned in the overview, it is best to design solutions based on JavaSpaces around the concept of object flows rather than attempting to, for example, create the equivalent of a database schema containing objects each of which has a unique key to allow direct addressing. This section provides some notes on problems often encountered when implementing JavaSpace-based solutions.
Tree-based algorithms can also suffer contention issues owing to the potential for conflict over the root node and the first few layers of children. Again, the normal solutions apply such as, high-fanout at the root node, splitting into separate trees, node caching etc.
In a number of usage patterns, it is desirable to arrange for
each Entry to have some form of unique
identifier. This presents a number of challenges in terms of state
maintenance including the need for clients to "remember" which id's
have been allocated.
This problem can be simplified as follows:
public class Id implements java.io.Serializable {
// Starts from zero, incremented by one for each new id
private long theSequenceNumber;
// Based on System.currentTimeMillis()
private long aTimestamp;
// Derived from InetAddress's byte[] representation.
private byte[] theIPAddress
}
You might also wish to look at the JINI 2.0 classes net.jini.id.UuidFactory
and net.jini.id.Uuid.
There are two important aspects of notify to be considered in all designs making use of JavaSpaces:
Thus notify cannot be considered to be reliable.....
A good approach to the use of notify is to have client's register for events and use that as the primary source of information for the client. Backing this up, you should occasionally use a take/read to query the JavaSpace for appropriate information. The take/read not only allows the programmer to recover from missing events but also to detect network/server issues which may be preventing event delivery, facilitating construction of suitable recovery mechanisms.
Another option is to have each client register for notify and then delegate event collection to an event mailbox situated close (in network terms) to the JavaSpaces server. The client can then rely solely on gathering events from the mailbox rather than having to use additional threads for background takes/reads. This is simpler but "more brittle" than the first solution. Locating the mailbox "close" to the server also reduces the likelihood of event loss due to fewer network hops and can also improve network utilization.
Many JavaSpaces examples and deployed JavaSpaces systems mix code for access to a JavaSpaces instance with code that performs other tasks in the same class. For small applications this is probably acceptable but more substantial systems should aim to separate the JavaSpaces code into a collection of library classes.
This makes code maintenance more easy by making it simpler to change the Entry "protocol" without disturbing anything else. It may also be useful future proofing because JavaSpaces may gain some form of code uploading feature for the purposes of accelerating performance and allowing implementation of a wider variety of systems.
See here and here for more discussion on code uploading in respect of JavaSpaces.
A common problem in many potential JavaSpaces applications is ensuring that only one instance of a particular Entry exists within a particular JavaSpace. This is seen in many scenarios including some forms of searching and multi-player games.
As yet, nobody has come up with a solution for this problem based solely on the use of the JavaSpaces API. However, the Blitz Project has implemented a distributed lock manager which provides a fault-tolerant locking service.
Basic usage would be something like:
This process ensures that only one entity will successfully create the unique Entry. Note care must be taken in deducing that an Entry does not exist. It may, for example, be necessary to have anyone manipulating the Entry, perform the operation under a lock or use some form of timeout such that if the Entry is not visible within a certain amount of time, it can be assumed it needs to be re-created.
The Blitz Lock Manager can be found here
Java and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the U. S. and other countries