Examples of calling one-way and two-way functions are made using interface Ix.
$interface+ rmi Ix
{
void Sum([in]int32 a,[in]int32 b,[out]int32& c); // c = a+b
void PrintInt([in]int32 x); // Print the value of x
};
Function calls through a stub are always asynchronous. All function calls on a given stub (whether for one-way or two-way functions) are invoked on the receiver in the same order they were invoked on the stub.
PrintInt() has no out-parameters and therefore is referred to as a one-way function. This means there will be no response message (not even an acknowledge) paired with the request message.
stub->PrintInt(1);
stub->PrintInt(2);
stub->PrintInt(3);
One-way functions are very efficient (e.g. 10 million function calls per second is possible on a modest machine).
In the interface Ix, Sum() has two in-parameters (a,b) and one out-parameter (c). A client can send outgoing messages through a stub like this
int32 c;
stub->Sum(10,20,c); // asynchronously calculate c = 10+20 = 30
Mark(rmiCaller);
Wait(rmiCaller);
assert(c == 30);
Even though Sum() is a two-way function it is called asynchronously. Just after the call on the stub the message may not yet have been delivered to the receiver and of course the out-parameter(s) typically won't have been assigned. The calls to Mark() and Wait() are necessary to ensure the response has been received and the out-parameter updated.
In more detail the following sequence of events occur
The advantage of the approach becomes more apparent when many calls on the stub are made and they are effectively performed in parallel, reducing the significant overhead of round trip network delays.
int c1, c2, c3;
stub->Sum(1,2,c1);
stub->Sum(5,4,c2);
stub->Sum(7,2,c3);
MarkAndWait(rmiCaller);
The stub allows for infinite write buffering (meaning that it won't block on I/O because a buffer has reached some upper bound). However when buffers reach 4MB asynchronous sending of buffered messages is automatically triggered.
Flush() on the RmiCaller is asynchronous - meaning that is causes flushing to occur but returns before waiting for the flush to have completed.