The experience we wish to emphasise is not that RPC cannot be changed. It is
that RPC is represented in modellers' minds as providing a base communications
paradigm, first and foremost, which is as like to local procedure as
possible, by default, and only relaxed later. This, as we shall see,
is what caused problems.
First, we must answer the inevitable question relating to Standards: Why not
OSF DCE RPC (or other)? The answer to this is non-technical, but stems
from our original motivation to stop using ANSA - it is not part of
the installed/bundled system (i.e. the same reason we do not want to
use TP4/CLNP instead of TCP/IP. Sun RPC is a widely available system
with stub compilers in the public domain.
The process of porting to Sun RPC was relatively straightforward, and
consists of the following (semi-automated) steps:
-
Converting the IDL to XDR suitable for processing by the Stub
generator utility, rpcgen. This consists of:
-
Conversion of IDL comment style to C.
-
Conversion of ;SPM_quot;INTERFACE/BEGIN/END;SPM_quot; to program, etc.
-
Conversion of TYPES, to XDR including constructors such as struct, enum.
-
Conversion of OPERATIONS to XDR procedures().
The conversion of operation parameter types involves merging call and
return parameters into single
call and return structures, since Sun RPC's XDR only supports a single
parameter and return value in this way. The only difference that
might have led to any problems is that both ANSA and Sun RPC provide variable
length arrays, and the CAR software makes extensive use of this type
constructor (though not part of the base C language that the CAR
system is written in). The stub generators in both cases convert this
into a structure which has both a length and value field, where the
value is a pointer type and the length is a number of objects. In both
cases, the same approach is taken. Thus storage allocation associated
with parameters can be dealt with in the same way as we pass between
the stub and the actual client and server application code.
-
Conversion of the DPL files to C with:
-
include of appropriate header fields to be generated from appropriate
XDR files
-
embedded calls to the relevant
Sun RPC runtime support in place of the ANSA annotations,
-
Conversion of exception handling code to Sun RPC exception handling
(instead of annotation, a return value of NULL pointer is used to
indicate an RPC protocol problem, at which point an external global
variable is available for testing what particular error has occurred)
together with appropriate actions and error messages.
-
Conversion of the Actual Server (called) C Code to match the stub declarations.
-
Conversion of Actual Client C (calling) Code to match stub
declarations.
This last step entails care, since the ANSA DPL annotation language
provides a primitive attempt at Object Orientedness, by tagging
procedure calls with the Interface name. This means that there could
in principle be name clashes. However, in well-engineered software
as the CAR system is, this turned out to be rare.
-
Finally, references to Interfaces, which are passed around between
clients and servers to build more flexible distributed programs (i.e.
provide an extra level of indirection, for instance in the
Notification Service) must be changed to refer to an instance of a
Sun RPC server - in our case, this is bound to a ;SPM_quot;host/port;SPM_quot; pair, so
can readily be implemented as a string or as a Unix sockaddr
structure.
The only step which entails some complexity is in dealing with the
inclusion of global definitions in XDR, in local XDR code - the
problem is this:
Given:
verbatim81
A stub generator produces
verbatim82
where xxxclnt.c and xxxsvc.c are the client and server stubs, respectively.
For these to compile, they must all include g.h, or, more cleanly,
s1.x and s2.x must include g.x, and the stub generator program uses
the C preprocessor to achieve the same thing.
The problem here lies in where a program that is a client of both
services needs to include the C definitions, s1.h and s2.h, there is a
repeated definition, which cannot be parsed.
The solutions are either to change the stub compiler so that it
generates unique include guarantees (the ifndef filenameIncluded
followed by define filenameIncluded, hack), or not to include the
g.x in s1.x and s2.x, and to postprocess the client and server stub
modules to include the global C definitions. All of this is unnecessary
in the ANSA RPC system, through its pseudo-object oriented approach. A
system built on C++ could avoid this mess completely (indeed, the
entire IDL/DPL, XDR support would then become unnecessary), since inheritence
could be used to carry out a lot of what is implemented using pre-processors
here.