### 8.1 Introduction to the Ada DSA

A critical feature of the Distributed Systems Annex (DSA) is that it allows the user to develop his application the same way whether this application is going to be executed as several programs on a distributed system, or as a single program on a non-distributed system. The DSA has been designed to minimize the source changes needed to convert an ordinary non-distributed program into a distributed program.

The simplest way to start with DSA is to develop the application on a non-distributed system. Of course, the design of the application should take into account the fact that some units are going to be accessed remotely. In order to write a distributed Ada program, it is necessary for the user to label by means of categorization pragmas some of library level compilation units of the application program. The units that require categorization are typically those that are called remotely, and those that provide the types used in remote invocations.

In order to ensure that distributed execution is possible, these units are restricted to contain only a limited set of Ada constructs. For instance, if the distributed system has no shared memory, shared variables must be forbidden. To specify the nature of these restrictions, the DSA provides several categorization pragmas, each of which excludes some language constructs from the categorized package.

Of course, the user can develop the non-distributed application with his usual software engineering environment. It is critical to note that the user needs no specialized tools to develop his/her distributed application. For instance, he can debug his application with the usual debugger. Note that a non-distributed program is not to be confused with a distributed application composed of only one program. The latter is built with the help of the configuration tool and includes the communication library.

Once the non-distributed version of the program is complete, it has to be configured into separate partitions. This step is surprisingly simple, compared to that of developing the application itself. The configuration step consists of mapping sets of compilation units into individual partitions, and specifying the mapping between partitions and nodes in the computer network. This mapping is specified and managed by means of a gnatdist configuration.

The distributed version of the user application should work as is, but even when a program can be built both as a non-distributed or a distributed program using the same source code, there may still be differences in program execution between the distributed and non-distributed versions. These differences are discussed in subsequent sections (see Pragma Asynchronous and Pragma All_Calls_Remote).

Developing a non-distributed application in order to distribute it later is the natural approach for a novice. Of course, it is not always possible to write a distributed application as a non-distributed application. For instance, a client/server application does not belong to this category because several instances of the client can be active at the same time. It is very easy to develop such an application using PolyORB; we shall describe how to do this in the following sections.