Porting to a less pure RPC

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:
  1. Converting the IDL to XDR suitable for processing by the Stub generator utility, rpcgen. This consists of: 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.
  2. Conversion of the DPL files to C with:
  3. Conversion of the Actual Server (called) C Code to match the stub declarations.
  4. 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.
  5. 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.