% to get hardcopy of this lecture, you need the following files (plus the
% normal latex and tex base directories):
%     lecture.tex:     latex source file
%     macros.tex:      figure macros
%     psfig.tex:       postscript figure (psfig) macro definition
%     pocs-header.sty: Principles of Computer Systems lecture latex header
%
% run the following programs:
% latex lecture
%   -> Creates lecture.dvi, plus latex intermediate files
% latex lecture
%   -> Run a second time to get cross-references right
% dvi2ps lecture |  egrep -v '^showpage$' > lecture.ps
%   -> Merges the figures with the text, can also pipe to lpr
%
\documentstyle[12pt,pocs-header]{article}
\Scribe{Irene Shen}
\Lecturer{Butler Lampson}
\LectureNumber{17}
\LectureDate{November 13, 1991}
\include{macros} % used to include figures in this document
\begin{document}
\MakeScribeTop

\section{Today's Topic: Remote Procedure Calls}
Today's topic is remote procedure calls.  This is a classic example of
a distributed communications primitive.  The RPC belongs to the {\bf
Session} layer of our network model; this is the first layer that an
applications programmer can use.   

The basic idea behind remote procedure calls is to try to emulate 
the semantics of local procedure calls as closely as possible for
reasons of familiarity and distributed system transparency.
There are several similarities between local and remote procedure
calls.  Both have the same procedure types, type checking, arguments,
results, and exceptions.  RPC also contains no implicit concurrency;
the programmer needs to incorporate concurrency into his system
explicitly.  This characteristic greatly simplifies RPC usage and
also parallels the semantics of normal procedure calls.   

RPC also differs from local procedure calls in several ways:
\begin{itemize}
\item the cost of RPC is 50-100 times greater than local procedure calls
\footnote{This cost, which tends to be ignored because of RPC
transparency, is significant.  For a 1 MIPS machine, an RPC Null call
typically takes 10-20 ms, under normal loads.  The best benchmark seen
is 2.5 ms.  OSF, DCE, and Sun are around 30-40 ms, with the times
scaled appropriately to account for machine speed.}  
\item the cost of copying large arguments across the network is larger since
simple pointers cannot be passed
\item the cost of dereferencing non-local pointers is greater since
this operation may not be straightforward 
\item the semantics for
      failures is different; the failure of a node may need to be reported
      to ensure RPC executes properly or may need to use pointers to
      reference a called node to enable work to be passed to a new node in
      case of failure
\item linking is more dynamic 
\end{itemize}

The point of RPC's is to allow a distributed system to be programmed in the
same way as a centralized system; if RPC's are implemented
effectively the same style can be used for procedure calls independent
of whether they are remote or local, and decisions about which
resources reside locally can be changed easily.  

\section{RPC Implementation Issues}
Implementation issues of RPCs may be divided into three categories:
\begin{itemize}
\item Naming:  obtaining a remote procedure identifier (address) from
      the name of the call
\item Marshalling/Unmarshalling:  encoding/decoding the
      arguments/return values of the RPC for/from transport
\item Transport: moving the call and return values between the nodes
\end{itemize}

\subsection{Naming}
A name is a label that has meaning to its user.  In general, a name
is converted to an address, which is interpreted by the communcation
system.  However, this address has no real meaning to the user.  In
general, different layers of the network view names and addresses
differently.  A value that is an address in one layer may be
considered a name in a higher layer.  To prevent any confusion, only
the names associated with pathnames are considered.  

Pathnames are hierarchical names, e.g., /a/b/c/23/144.  A pathname is
composed of names that have meaning to the user (a, b, c) and names,
like addresses, that do not have meaning to the user (23, 144).
Every pathname must have a root (/) to specify the starting point of the
path.  There must be some method external to the naming scheme to
identify and locate the root.  Locating the root is a more fragile
function since state may change.  There exist many implementations for
pathnames.  The basic abstraction is as follows:
\begin{verbatim}
	D  = N -> (D | V)        % directory
	PN = SEQ[N]              % pathname

	% if return  V, then pathname completely resolved
	% if return (D, PN), then pathname is partially resolved
	% and work is passed on
	PROC Lookup(d, pn) -> [(D, PN) |  V]
	
	% sets pn to value v
	PROC Set(d, pn, v)

	% lists everyting in d
	PROC Enum(d) -> SET[N]
\end{verbatim}
Many current file systems use hierarchical naming.

Addresses also tend to be hierarchical, but their packaging often
obscures this characteristic.  Take for example a UDP address.  The UDP
address contains:
\[
\begin{array}{lc}
\left. \mbox{ } \bullet \mbox{ 48-bit LAN Address} \right\} & 
\mbox{Header}\\
\left. \begin{array}{l}
	\bullet \mbox{ IP Address} \\
	\bullet \mbox{ Port Number} \\
	\bullet \mbox{ Object Number}	
       \end{array}
 \right\} & \mbox{Fundamental (encapsulated)}
\end{array}
\]
The LAN address header encapsulates
the fundamental UDP address.  The fundamental part of the UDP address
includes the IP address, the port number, and the object number.  The
IP address specifies how to get to the desired machine, the port
number the proper address space, and the object number the specific
object.  Figure~\ref{udp} shows a graphical interpretation of the UDP
\begin{figure}
%\vspace{2.5in}
\centerline{\psfig{width=6.5in,figure=udp.ps}}
\caption{Fundamental UDP address interpretation.}
\label{udp}
\end{figure}
address fields.  For an RPC, the object number actually consists of
two parts, the interface number and the procedure number.  This change
can viewed in Figure~\ref{udp} as one more level of indirection (table
lookup) in the proper address space before getting to the desired
procedure entry point (object).  

The fundamental part of the UDP address is known as a network
reference.  If a failure occurs during and RPC, either the network
reference must be invalidated or the naming scheme should be
designed to be transparent to actual machine addresses.  

\subsection{Marshalling or How RPC Works}
Marshalling involves converting the RPC into the proper form for
transport.  Unmarshalling converts the return values from transport
form to usable form.  Marshalling utilizes network references, which
are essentially pointers in a global reference frame.  There are
basically two methods to marshal an RPC.  The first requires copying
the pointer and then copying the local contents of the pointer to fill
up remote storage.  The RPC executes using the copied data.  If the
pointer is a real reference, a second method for marshalling may be
used that converts the pointer into a network reference.  This
conversion specifies the IP address and port number, then allocates an
object number on the remote machine.  If the reference already exists
on the remote machine, then this current net reference is used; there
is no need to allocate another object number.  

RPC works by transferring control to a local stub that performs all
the dirty marshalling and unmarshalling work.  For the local
machine, the stub receives the call, marshals the arguments, sends the
data, receives the reply, unmarshals the return values, and passes
them back to the caller.  In this way, an RPC looks like just another
local call.  Similarly, a remote machine also has a stub mechanism
that receives the call, unmarshals the arguments, calls the requested
local procedure, marshals the return values, and sends the return.  In
this way, processing remote procedure calls is just like processsing
local calls.  

Stubs perform marshalling and unmarshalling by creating and parsing
network packets.  A network packet contains:  
\begin{itemize}
\item IP header
\item UDP header - destination and source IP addresses, port number
\item RPC identifier (call id) - interface number, procedure number
\item encoded arguments
\end{itemize}
The encoded arguments may be considered to be contained in a buffer.
The stub uses a procedure {\bf Send(p, b)} to build and send the
network packet.  {\bf p} specifies the procedure and {\bf b} is a
pointer to the argument buffer.  The resulting data must reside in
shared memory to allow the transport mechanism to access the packet.  
{\bf Send} is actually composed of three procedures:
\begin{itemize}
\item {\bf Start(p) -$>$ B} creates a packet and starts filling up
      the buffer to transport 
\item {\bf Next(b, last) -$>$ B} if the size of the arguments is larger than
      the buffer size, keep sending more buffers until {\bf last =
      FALSE}; the stub knows when to stop sending buffers
\item {\bf End(b)} Get result and unmarshall.
\end{itemize}
The first two procedures perform the marshalling function of the stub.
The third procedure performs unmarshalling.  

\subsection{Transport}
The basic requirement for RPC transport is that a call message is sent
and its reply received.  This depends heavily on AOM message delivery.
Different transport systems, listed in increasingly preferred order, are:
\begin{itemize}
\item (1) use mail as tranport
\item (2) use shared memory
\item (3) use TCP
\item (4) piggy back ACKs on other messages (use AOM)
\end{itemize}
Whichever transport mechanism is chosen, there still exists the need
to control load in the transport mechanism.

\end{document}
