2. How do I locate and compose operators into a path?
A path is composed of two endpoints, the source and destination operators, and zero or more intermediate operators. A path can be created only by the source operator, from the source, through the intermediate operators and, finally, to the destination. If two way communication is required (two paths) between source and destination operator, then the destination will have to request a path to the source (basically, the roles of source and destination operators get inverted). The following sections will describe how to write source, destination and intermediate operators; all three types of operators are very similar.
All operators in a path, including the source and destination operators, must inherit from the Operator class which manages all soft state related to a path. Operators are required to implement only the "run" method. The intermediate operators have their operator XML descriptions registered with the PathXSetService, but the source and destination operators don't have their operator XML descriptions registered anywhere. Thus, they must provide XML descriptions in the directory where the Java files exist for source and destination operators; these descriptions are needed by the APC to match the operators. The reasons for not making the source and destination operators register their XMLdescriptions with the PathXSetService are ommitted from this section.
The path is initially created by the source operator which can build the path manually or automatically using the Automatic Path Creator. The path is then instantiated (operators started) and implemented (operators connected).
The following code creates a path using the APC, instantiates and implements it.
public void createPathToDestination(OperatorIF destination)
{
PathDescription pd = null;
AutomaticPathCreaterServiceIF apc = null;
try {
apc = AutomaticPathCreatorService.loadSDSAutomaticPathCreator();
pd = apc.createLogicalPath(new PathDescription(), this,
destination);
}
catch (Exception e) {
System.out.println("Failed to create logical path
using APC: " + e);
}
try {
setPathDescription(pd, getIdentification());
pd = PathInstantiator.instantiatePath(pd);
pd = PathImplementer.implementPath(pd);
}
catch (Exception e) {
System.out.println("Couldn't instantiate or implement
logical path: " + e);
}
The code is self explanatory, but few things should be noted:
We're done with specific code to the source operator. All operators in the path will contain similar code for the "run" method presented below.
public void run() {
Object pathID = getPathID(Thread.currentThread());
BufferedReader inputStream = new BufferedReader(new InputStreamReader(getReader(pathID)));
BufferedWriter outputStream = new BufferedWriter( new OutputStreamWriter(getWriter(pathID)));
try {
read from inputStream
write to outputStream
}
catch (InterruptedPathException e) {
/* Take appropriate action */
}
catch (NoPathFoundException e) {
/* Take appropriate action */
}
catch (Exception e) {
System.out.println("Got exception: " + e);
}
}
There is an input and output stream for each path going through an operator (the source operator will only have the output stream, while the destination operator will only have the input stream). The parent class Operator maintains this soft state. Given a thread object, we can obtain the path ID of the path handled by that thread. Once we have a path ID, we can get the input and output streams associated with a path going through the operator (there could be multiple paths, handled by different threads, going through an operator).
The meaning of the InterruptedPathException and NoPathFoundException are explained in the next section.
Back to [Paths]