Package mandala.rami

Specification and implementation of the Reflective Asynchronous Method Invocation.

See:
          Description

Interface Summary
AsynchronousReference Asynchronous reference on an object.
AsynchronousReferencePair An AsynchronousReferencePair is an asynchronous reference wich represents a pair of asynchronous references.
Callback A Callback instance defines the work to do once an asynchronous method invocation had terminated.
CallbackManager This class defines methods to manage Callback instances related to AsynchronousReference.
Framework.Factory The Factory used to instanciate AsynchronousReference implementation.
FutureClient This interface represents the final future object any client must use to deal with an asynchronous method invocation.
FutureServer This interface represents the informations a future object used by any server to handle an asynchronous method invocation must provide.
InvocationEventsWaiter This interface defines the behavior a waiter of an asynchronous method invocation must have.
InvocationInfo This interface provides methods to get informations on an asynchronous method invocation.
InvocationObserver This interface defines the behavior an observer of an asynchronous method invocation must have.
MethodResult This interface represents the result returned by an asynchronous method invocation.
Reference  
ResultUpdater This interface provides methods to update a future object used to handle an asynchronous method invocation.
 

Class Summary
AbstractARFactory This abstract class provides all the necessary method to customize the CallbackManager used when creating AsynchronousReference implementation instance.
AbstractAsynchronousReference Abstract implementation of the AsynchronousReference interface.
AbstractFutureClient Abstract implementation of the FutureClient interface.
AsynchronousReferencePair.CallReflection Reflection of the AsynchronousReference.call(MethodOp, Object[]) method.
Framework This class is the starting point in RAMI.
 

Package mandala.rami Description

Specification and implementation of the Reflective Asynchronous Method Invocation.

Package Specification

Asynchronous reference concept

RAMI defines the interface AsynchronousReference which represents an asynchronous reference on an object.
To understand this concept, we define the following notations :
if i is an instance of a class C, R(i : C) is a synchronous reference on i and AR(i : C) is an asynchronous reference on i.

Consider the Java code below :

MyClass myObject1 = new MyClass();
MyClass myObject2 = myObject1;
The variable myObject1 is of type MyClass and references synchronously the instance (which has no given name) of the class MyClass. If this instance is called i, then we will note myObject1 : MyClass = R(i : MyClass) to mean : "the variable myObject1 of declared type MyClass references synchronously the instance i of the class MyClass. As you could guess, we also have myObject2 : MyClass = R(i : MyClass).

We use the notation x = AR(i) when the declared type of the variable x and the class of the instance i is not meaningful.

Singleton property

Each implementation of the AsynchronousReference interface must implement a variant of singleton design pattern defined as follow:
Consider:

then, ar1 == ar2 if and only if r1 == r2 (which implies that i1 == i2).

Consider the example below :

Integer a = new Integer(5); // (1)
Integer b = new Integer(5); // (2)
Object o = a;
Now , if we note i the instance of java.lang.Integer created by (1) and j the one created by (2), we have :
a : Integer = R(i : Integer),
b : Integer = R(j : Integer),
o : Object  = R(i : Integer)
And, as you could guessed, we have a != b even if a.equals(b) and b.equals(a). We also have a == o even if their declaring type are not the same.

Hence, in standard Java, if v = R(i) and v' = R(i'), v == v' returns true if and only if i == i' i.e. if i and i' are the same instance.

RAMI provides the same semantic for asynchronous references. Hence, if v = AR(i) and v' = AR(i'), v == v' returns true if and only if i == i' i.e. if i and i' are the same instance.

Hence, using RAMI, when you have two asynchronous references, comparing them with the '==' operator has the same behaviour as with synchronous references.

Instantiation of asynchronous references

End user do not instantiate asynchronous references directly using the new operator as usual (AsynchronousReference implementations constructors must be declared at least protected in order to ensure the singleton property as mentionned below). Instead, they use the factory design pattern in the interface Framework.Factory along with the method Framework.setFactory(mandala.rami.Framework.Factory) in order to customize the type of asynchronous reference to use.
The default factory used is ARFactory which creates instances of the AsynchronousReferenceImpl classes. Any factory may be set using the method Framework.setFactory(mandala.rami.Framework.Factory).

Consequence of the singleton property for asynchronous reference implementors.

Creating a standard synchronous reference is just a matter of invoking new on the needed class. Since Java does not support asynchronous reference directly, RAMI proposes the AsynchronousReference interface which defines the semantic and the behaviour of asynchronous references. But, the instanciation of an AsynchronousReference implementation class cannot be done with the standard new operator due to the singleton property implementors must ensure. Hence, implementors are encourage to use the SingletonGiver and to replace their standard constructor:

// Object is the object to get an asynchronous reference on
// ParamJ is a parameter my own implementation needs to 
// create an asynchronous reference
public MyAsynchronousReference(Object object,
                               Param1 param1,
                               ...,
                               ParamN paramN) {
     ...
}
by the following code :
protected MyAsynchronousReference(Object object,
                                  Param1 param1,
                                  ...,
                                  ParamN paramN) {
     ...
}

private static final SingletonGiver singletonGiver =     
        new SingletonGiver(new SingletonGiver.Factory() {
                // Implements my singleton policy
                public Object newInstance(Object object, Object[] args) {
                    // if args.length == 1 it means singleton is used in
                    // deserialization (see readResolve() below) and that
                    // args[0] contains the reference to return.
                    if (args.length == 1) {
                        return args[0];
                    }

                    if (args.length == N) {
                        return new MyAsynchronousReference(object,
                                                           param1,
                                                           ...,
                                                           paramN);
                    }

                    throw new IllegalArgumentException("Wrong number of " + 
                                                       "arguments!");
                }
       });

public static MyAsynchronousReference getInstance(Object object,
                                                  Param1 param1,
                                                  ..., 
                                                  ParamN paramN) {

    return (MyAsynchronousReference) 
            singletonGiver.getInstance(object, 
                                       new Object[]{param1,
                                                    ...
                                                    paramN});
}

// Warning : Singleton must be respected !
// readResolve() help us in this way !
private Object readResolve() throws ObjectStreamException {
// Do not create a MyAsynchronousReference with 'new' as in
// getInstance(), use 'this' instead
        return singletonGiver.getInstance(object, 
                                          new Object[]{this});
}
which ensure the singleton property. A class which implements the Framework.Factory interface must be provided for the end-user who usually do not invoke the above getInstance() method directly (see Instanciating Asynchronous Reference above for details.)

Transparency

Using instances of implementation of the AsynchronousReference interface is painfull. Instead, RAMI provides transparency which allows developpers to deal with asynchronous references in a more natural way. Transparency is provided by the mandala.rami.transparency package.



Mandala help mailing list