next up previous
Next: About this document ... Up: Transparent RPC Previous: Semantics


There are several basic components that work together to allow a client to make a distributed invocation in a server that implements a remote interface:

Client Code

Client code, C, written by the client programmer, that makes the remote invocation. For instance, a call of the form:

i : = P (s)
where P is a procedure defined in some remote interface.

Server Code

The server code, S, written by the server programmer, that implements the remote procedure. For instance a procedure of the form:

procedure P (s: S): int {
   /* implement the functionality of P */
   return (result)

Client Stub

A client stub, for each remote procedure P, generated by the interface compiler, that is linked to the client code and is called by C when it makes the remote invocation. C cannot call the remote P directly since they are in separately linked address spaces. Therefore, what it actually does is call the client stub, which marshalls the parameters, talks to the RPC runtime to send a remote message, receives a return message from the runtime, unmarshalls the results, and returns it to C. Thus, the form of the stub is:

procedure P (s: S): int {
  /*  marshall s */
   xdr_int (xdrsp, s->f1)
   xdr_float (xdrsp, s->f2)
  /* send  message via RPC runtime, filling in procedure (and dispatcher) ID */
  /* receive result from RPC runtime */
  /* unmarshall result */
   xdr_int (xdrsp, result);
   return (result)

Server Stub

A server stub, for each each remote procedure P, generated by the interface compiler, that is linked to the server code, S, and invokes the implementation of P. It is the dual of the client stub - It unmarshalls the parameters and marshalls the results. Thus, its form is:

procedure PServerStub {
   /* unmarshall s */
   xdr_int (xdrsp, s->f1);
   xdr_float (xdrsp, s->f2);
   /* call P */
   result := P (s);
   /* marshall result */
   xdr_int (xdrsp, result);
   /* send result via RPC runtime */

Server Dispatcher

A dispatcher, generated by the RPC system for each interface, and linked to the server, which receives an incoming call request and invokes the corresponding server stub. The call request identifies the procedure to be invoked and the dispatcher is responsible for mapping it to the server stub. This mapping is generated at interface compilation time.

XDR Routines

The XDR routines for predefined (simple) types are written by the implementer of the RPC system, while the routines for user-defined types are generated by the compiler based on the definitions of the types of the arguments of the remote procedures.

RPC Runtime

The RPC runtime, which exists at both the client and server sites. It is responsible for sending and receiving messages from remote sites. It is also responsible for binding remote calls and forwarding messages to the correct dispatcher. It can, like Sun RPC, simply use a general, lower-level networking layer such as UDP or TCP/IP to send and receive messages. However, it is possible to define efficient, specialised communication protocols for implementing transparent RPC, as illustrated by Cedar.

Specialised Protocols

The Cedar system uses a special network protocol to support at-most-once RPC semantics. Such semantics can be supported on top of a connection-based reliable protocol such as TCP/IP. However, they are not optimal for RPC mechanisms, since they have been designed to support asynchronous reliable transfer of bulk data such as files. There are two possible optimisations possible in a specialised protocol:

Implicit Sessions: A bulk data protocol requires explicit opening and closing of sessions. An RPC implementation on top of such a protocol can use two main approaches to opening/closing sessions: First, a client machine can open a session with each possible server machine with which the client may communicate. Second, the client machine can open/close the connection before/after each call. The first approach amortizes the cost of opening/closing connections over all calls to a server machine, but uses more connections (which are scarce resources) at any one time and requires probe messages inquiring the status of a server machine to be sent even when no RPC is active. The second approach, on the other hand, requires connections to be active and pinged only during the procedure call but requires an explicit opening/closing per call. A specialised protocol can offer the advantages of both approaches by implicitly opening/closing a connection at the start/termination of a call.

Implicit Acknowledgement: A bulk-data protocol can result in each packet being acknowledged. In a specialised protocol, the RPC reply can acknowledge the last packet. This can result in no acknowledgments being sent for RPC calls with small arguments.

The Cedar implementation shows how a specialised protocol may be implemented. Each call is assigned an id from an increasing sequence of ids generated by the system. The RPC runtime at the client machine sends to the receiver the following client information: call id, dispatcher id, procedure id, and arguments. The RPC runtime at the server machine sends back to the client: call id and results. The client runtime breaks the client information into one or more packets, encloses the packet number, and asks for an acknowledgement for all packets except the last one, which is acknowledged by the reply. After each packet, it waits for an ack/reply. If it does not receive the ack/reply within a certain time, T, it resends the packet, asking for an explicit ack (even for the last packet). After receiving all acks, the client may need to wait for the RPC to finish. It periodically sends probe packets (after P time units) to check the status of the server machine. If it does not receive acks to normal/probe to packets after a certain number, R, of retransmissions, it determines that the server machine has crashed and reports an exception to the client program. Once it receives a reply, it waits for a certain period of time, D, for another call to the server. If a call is made within that period, then that call serves as an ack for the reply of the previous call. Otherwise, the client explicitly sends an ack.

Under this protocol, short calls (duration less than T) with small arguments (fitting in one packet) and occurring frequently (inter call delay less than D) resulting in no lost messages require only two messages to be communicated. A long call (duration greater than T but less than P - not requiring probe packets) requires an additional retransmission of the argument and its explicit ack. A really long call requires transmissions and acks of probe packets. A call that is not followed quickly by another call requires an ack for the reply.

Thus, this procotol is optimised for the first case: it is not possible to do better in this case. A bulk transfer protocol would require additional open and close messages and an additional argument ack unless it is piggybacked on the reply message. On the other hand, this protocol may result in more messages to be communicated for other cases since it makes a client wait for an ack for a previous packet before sending the next one. As a result, the server machine must ack all packets except the last one. A bulk data transfer protocol allows multiple packets to have outstanding acks and allows one server message to serve as an ack for a sequence of client messages. Thus, this protocol follows the principle of making the usual case efficient while making the unusual cases possible but not necessarily efficient.

next up previous
Next: About this document ... Up: Transparent RPC Previous: Semantics
Prasun Dewan 2006-02-02