miniSpace is a general-purpose coordination mechanism inspired after the Linda Coordination Language and JavaSpaces. It is by no means an attempt to implement any of those, we just implemented the minimum set of concepts we needed in our own projects.
You can think about a Space instance as being like a Map where its entries are lists of objects and its operations are fully synchronized.
There are three basic operations:
In addition to those three basic operations it also has a few handy methods:
timeout milliseconds
for a given entry; otherwise, return null.
timeout milliseconds for
a given entry; otherwise, return null
Let's have a look at a simple example, we will put two Strings in the Space under the key name "Test" (we call them 'queues') by using the out operation. The first string equals to "Hello ", and the second one equals to "World".
Then we will take and print one entry at a time off the "Test" queue by using the in operation.
Finally we will read (rd) that queue using the rdp (read-probe) operation. It should be null (because there were just two entries under the name 'Test' and we have already taken them off the Space).
import org.jpos.space.*;
Space sp = SpaceFactory.getSpace(); // get a reference to the default Space
sp.out ("Test", "Hello "); // put "Hello " in the "Test" queue
sp.out ("Test", "World"); // put "World" in the "Test" queue
System.out.print (sp.in ("Test")); // should return the first entry
System.out.print (sp.in ("Test")); // should return the second entry
if (sp.rdp ("Test") == null) // should be null
System.out.println (".");
--- output ---
Hello World.
We encourage you to play with the previous code and we suggest you perform some of the following variations in order to understand how it works:
public void run() {
Space sp = SpaceFactory.getSpace();
for (;;) {
Runnable r = (Runnable) sp.in ("MyPool");
try {
r.run();
} catch (Exception e) {
e.printStackTrace();
}
}
}
When you need to run something controlled by the thread pool,
you would just queue a Runnable object into the "MyPool" queue,
e.g.:
Space sp = SpaceFactory.getSpace();
sp.out ("MyPool", MyRunnable);
Object ticket = null;
try {
ticket = sp.in ("TransactionTickets");
...
...
...
} finally {
sp.out ("TransactionTickets", ticket); // back to the ticket pool
}
Space sp = SpaceFactory.getSpace();
for (;;) {
BigDecimal exchangeRate = getExchangeRateFromDB(...);
sp.out ("ExchangeRate", exchangeRate, 120000L);
Thread.sleep (110000L); // get a new one before it expires ...
}
Then any client code can just block waiting for a valid and up-to-date
ExchangeRate object to be available in the space, e.g.:
BigDecimal exchangeRate = (BigDecimal) sp.in ("ExchangeRate");
or better yet, wait for a reasonable time for a valid exchange rate
to be available in the Space (think database down) and throw an
exception if it doesn't get available.
BigDecimal exchangeRate = (BigDecimal) sp.in ("ExchangeRate", 10000L);
if (exchangeRate == null)
throw new XXXException ("Exchange rate is not available");
for (;;) {
CardData cd = readCardData(...);
SpaceUtil.wipe (sp, "CARDDATA"); // clear buffer
sp.out ("CARDDATA", cd, 60000L); // buffered for just 1 minute
}
Then at the UI level we can asynchroneously ask for the transaction type,
amount, etc. At any point where we need the card data, we would just call:
// gives the operator up to two minutes to swipe the card
CardData cd = (CardData) sp.in ("CARDDATA", 120000L);
...
...
When you call SpaceFactory.getSpace() you are actually getting
an instance of TSpace. That Space gets registered under the name
tspace:default. So calling SpaceFactory.getSpace() is
exactly the same as calling
SpaceFactory.getSpace("tspace:default").
You can create as many Spaces as you want, and you can make them anonymous if you go directly to the Space constructur instead of using the SpaceFactory helper class.
There's a very useful space implementation called JDBMSpace. It is a persistent space implementation that uses a JDBM database as its back end. The result is that everything you write there will remain valid across JVM runs.
You can use a JDBMSpace by calling:
Space sp = SpaceFactory ("jdbm:mypersistentspace");
You can also specify an optional path for your JDBM database:
Space sp = SpaceFactory ("jdbm:mypersistentspace:/tmp/persistentspace");
You can get additional information in the project page at Google Code.