Reolite
Reolite is a fairly functional, non-distributed version of the coordination language Reo based on the Connector Colouring paper of Dave Clarke, David Costa and Farhad Arbab. Reolite is implemented as a Java library, and thus the style of programming is more object-oriented in flavour than the approach outlined in Farhab Arbab's original paper.
Reolite can be run in two modes: the Reo mode, and the colouring mode.
In Reo mode, one can code up a connector and write some components which use it (using writes and takes). The components and the Reo engine are Java threads. This can be used as a simulation environment for coordinating component written as Java threads (or wrapped by Java threads). A version of split and join are also available, and channel ends can be sent along channels, so there is the possibility for doings some fancy tricks.
In Colouring mode, one can build a connector and ask for its colouring table, just as we do in the paper. This is at the core of Reo mode's implementation.
Implemented features includes:
- synchronous channels, lossy syncs, (a)synchronous drains, synchronous spouts (which only give constants at this stage), fifo1;
- a replicator
- a merger
- a priority merger
- a passive merger — this kind of merger preserves the priority decisions made elsewhere in the circuit.
Missing:
- full Reo nodes (replaced by replicators and mergers)
- connect/disconnect operations
- distributedness, mobility
- robustness
- hiding
- patterns, data-dependent connectors (such as filter)
Download
The implementation is available (privately) at this link.
Building
To build and run the project you need Ant (or the NetBeans IDE).
To build, type:
ant compileTo run, type:
ant run
Building a Connector
The first thing a Reo can do is build connectors. The following code in src/reo/connector/ExclusiveRouter.java constructs an exclusive router connector. The following code constructs an exclusive router. Once nodes have been implemented, the code here will be much simpler.
package reo.connector;
import reo.primitive.*;
import reo.core.*;
public class ExclusiveRouter {
private InputEnd in;
private OutputEnd left;
private OutputEnd right;
/** Creates a new instance of ExclusiveRouter */
public ExclusiveRouter() {
Replicator r1 = new Replicator(), r2 = new Replicator(), r3 = new Replicator(),
r4 = new Replicator();
LossySync ls1 = new LossySync(), ls2 = new LossySync();
SyncDrain sd = new SyncDrain();
Merger mg = new Merger();
// set boundary ends
in = r1.getIn();
left = r3.getLeft();
right = r4.getRight();
// build 3-way replicate
r1.getLeft().join(r2.getIn());
// connect to two lossys and sync drain
r2.getLeft().join(ls1.getLeft());
r2.getRight().join(sd.getLeft());
r1.getRight().join(ls2.getLeft());
// connect lossy 1 to replicator 3
ls1.getRight().join(r3.getIn());
// connect lossy 2 to replicator 4
ls2.getRight().join(r4.getIn());
// connect sync drain to merger
sd.getRight().join(mg.getOut());
// connect two replicators (3 & 4) to merger
r3.getRight().join(mg.getLeft());
r4.getLeft().join(mg.getRight());
}
public InputEnd getIn() {
return in;
}
public OutputEnd getLeft() {
return left;
}
public OutputEnd getRight() {
return right;
}
}
Reo Mode
Reo mode aims to mimic how Reo would operate as a coordination model connecting components."Components"
In directory src/reo/component/dummy are two dummy components written to interact with a Reo connector. One performs writes, the other reads.
Here is the Reader (src/reo/component/dummy/Reader.java):
package reo.component.dummy;
import reo.component.Component;
import reo.core.OutputEnd;
import reo.core.TimedOutException;
public class ReaderComponent extends Thread implements Component {
private OutputEnd oe;
public ReaderComponent(OutputEnd oe) {
this.oe = oe;
}
public void run() {
oe.connect(this);
for (int i = 1; i < 10; i++) {
try {
Object mess = oe.take(2000);
System.out.println("Reader:: Rcvd <<" + mess + ">>");
try {
sleep(300);
} catch (InterruptedException ie) {
System.out.println("Reader:: sleep interrupted.");
}
} catch (TimedOutException toe) {
System.out.println("Reader:: Timed out");
}
}
System.out.println("Reader:: End");
reo.core.ReoEngine.getEngine().signalStop();
}
}
Here is the Writer (src/reo/component/dummy/Writer.java):
package reo.component.dummy;
import reo.component.Component;
import reo.core.InputEnd;
import reo.core.TimedOutException;
public class WriterComponent extends Thread implements Component {
private InputEnd ie;
public WriterComponent(InputEnd ie) {
this.ie = ie;
}
public void run() {
ie.connect(this);
for (int i = 1; i < 10; i++) {
String mesg = "Message " + i;
try {
System.out.println("WriterC:: Send <<" + mesg + ">>");
ie.write(mesg, 200);
System.out.println("WriterC:: Sent <<" + mesg + ">>");
} catch (TimedOutException toe) {
System.out.println("WriterC:: Fail <<" + mesg + ">> timed out.");
}
}
try {
sleep(100);
} catch (InterruptedException ie) {
System.out.println("WriterC:: sleep interrupted.");
}
System.out.println("WriterC:: End.");
}
}
Here is the main method (in src/reo/Main.java) which ties these together with a connector.
package reo;
import reo.core.*;
import reo.primitive.*;
import reo.component.dummy.WriterComponent;
import reo.component.dummy.ReaderComponent;
public class Main {
public static void main(String[] args) {
ReoEngine reo = ReoEngine.getEngine();
SyncChannel chan1 = new SyncChannel();
InputEnd in1 = chan1.getLeft();
OutputEnd out1 = chan1.getRight();
LossySync chan2 = new LossySync();
InputEnd in2 = chan2.getLeft();
OutputEnd out2 = chan2.getRight();
out1.join(in2);
WriterComponent wc = new WriterComponent(in1);
ReaderComponent rc = new ReaderComponent(out2);
// start components running
new Thread(wc).start();
new Thread(rc).start();
reo.start();
}
}
Colouring Mode
The following (in src/reo/Colour.java) is an example of how to produce the colourings for a particular connector. This is pretty rudimentary at the moment, and the output leaves much to be desired.
package reo;
import reo.core.*;
import reo.primitive.*;
import reo.connector.ExclusiveRouter;
final public class Colour {
public static void main(String[] args) {
ReoEngine.colourMode = true;
ExclusiveRouter ex = new ExclusiveRouter();
ReoEngine.getEngine().printAllColourings();
}
}
Adding Your Own Connector
TODOMisc
Presently, there is no documentation beyond the code itself. If you open the unpacked code in NetBeans, you'll have a nice way of navigating through and running the code.
Questions, comments, bug fixes, examples, anything, are welcome. This is a good platform for future student projects and experiments. What do you want to coordinate today? Coordination! Be in it.
Dave - Reolite maintainer. dave AT cwi.nl
Release notes
0.0.3
- Removed the factory from ReoEngine for creating channels. Primitives now register themselves. Still not a 100% satisfactory solution.
- Renamed reo.channel.ConstantAsyncSpout to reo.channel.ConstAsyncSpout. Similarly for ConstantSyncSpout.
- Merged packages reo.channel and reo.connector (which contained replicators and mergers) into package reo.primitive.
- Added reo.connector as place for library of connectors.
- Added reo.connector.ExclusiveRouter.
- Added harness for displaying connector colourings.
- Made it simpler to use colouring mode.
- Added facility for Nikolay's f-connectors. They only work properly in totally synchronous circuits, though.
- Added timeouts to writes and takes. These are passive in that they wait until one round of reo-ing is done before they timeout.
- Rewrote the engine so that it's state is explicit (albeit distributed), rather than implicit in the various nodes, ends, and channels.
- Implemented the flip rule -- unsure whether it actually reduces tables.
- Implemented filtering on tables to remove duplicate entries for composites in order to keep their size down. It DRASTICALLY reduces the size.
0.0.2
- Added FIFO1 buffer.
0.0.1
- Initial Release
Last modified: Mon Oct 24 11:51:37 CEST 2005