Table of Contents
Introduction
Welcome to the first of a series of tutorials detailing the construction, configuration and execution of distributed Ada applications. The tutorials are intended to ease a newcomers entry to building distributed applications with Ada.
More information on DSA can be found here:
Annex E: Distributed Systems
The Distributed Systems Annex describes the facilities available for implementing distributed systems. A distributed systems is basically a program where selected parts of the program run on different processing and storage nodes. DSA in short enables you to distribute workload easily across multiple physical computers and it makes network communication completely transparent among the clients and servers.
The possibilities with DSA are nearly endless, so it is well-worth the effort to learn a bit about this marvelous technology.
Design
The hello DSA application is perhaps the simplest possible example of a DSA application.
The main application entities are:
Server:
- exists as a single instance
- provides a single service greet, which returns a greeting string to a Client
- implemented as a DSA remote call interface package
Client:
- many instances may exist
- a Client instance will request the Server's greet message and displays it, in an infinite loop.
- implemented as a normal Ada package
Applets:
- Two applets exist to launch the server or a client
- These are implemented as normal Ada main subprograms
The source code is simple enough that it may be presented herein …
Source Code
Server:
Copy the following into a file called server.ads.
package Server is pragma remote_call_Interface; function Greeting return String; end Server;
Copy the following into a file called server.adb.
package body Server is function Greeting return String is begin return "Greetings, Earthling."; end; end Server;
Client:
Copy the following into a file called client.ads.
package Client is procedure Start; end Client;
Copy the following into a file called client.adb.
with Server; with ada.Text_IO; use ada.Text_IO; package body Client is procedure Start is begin loop delay 1.0; put_Line ("Server says: '" & Server.Greeting); end loop; end; end Client;
Applets:
Copy the following into a file called start_server.adb.
with Client; with Server; procedure start_Server is begin loop delay 0.5; end loop; end;
Copy the following into a file called start_client.adb.
with Client; procedure start_Client is begin Client.start; end;
Preparation
Of course, we need an Ada compiler and DSA implementation. A good choice might be the Gnat and Polyorb (GPL11) versions available at Libre.
Polyorb will need to be built from source via:
$ ./configure --enable-debug --with-appli-perso="dsa" --with-proto-perso="giop" $ make $ make install
Now that our tools are installed, we can build the distributed application…
Build
To build a distributed application, po_gnatdist is used, instead of gnatmake.
Instead of producing a single executable (as gnatmake does), po_gnatdist will produce an executable for each partition involved in the distributed application. In our case, an executable for each of the Server partition and Client partition will be produced.
po_gnatdist is fed a build-time configuration file, which tells po_gnatdist which package belongs to which partition executable.
For Greetings Earthling, the following dsa.cfg is our build-time configuration for po_gnatdist.
Copy the following to a file called dsa.cfg.
configuration DSA is pragma Starter (none); -- Tell 'po_gnatdist' to not create any startup script or launcher (more on this in a lter tute). -- We will launch our Server and Client partitions manually from a console. -- Server server_Partition : partition := (Server); -- Declare the Server partition and assign the 'Server' remote call interface package to this partition. procedure start_Server is in server_Partition; -- Tell po_gnatdist that the 'start_Server' procedure is the the Servers 'main' subprogram or launcher. -- Client client_Partition : partition; -- Declare the Client partition (which has no remote call interface package associated with it, so no 'initialisation' is required). procedure start_Client; -- Declare the Clients 'main' subprogram or launcher. for client_Partition'Main use start_Client; -- Tell po_gnatdist to assign the above declared 'start_Client' procedure as the Clients 'main' subprogram or launcher. for client_Partition'Termination use Local_Termination; -- Tell po_Gnatdist that Clients may terminate locally (more on this later). -- Misc for Partition'Directory use "bin"; -- Ask po_gnatdist to place the built Client and Server partition executables in the './bin' sub-folder. end DSA;
Finally, we invoke the build with:
$ po_gnatdist dsa.cfg
This should build both the Server and Client partition executables and place them in the ./bin directory.
Trial
Now that both client and server partitions have been built, we can test them, first locally within a LAN, and then across a WAN via the internet.
Local Area Net Test
In Brief
- Run-time configuration: (polyorb.conf)
- start po_cos_naming:
- start Server:
- start Client:
Detailed
Run these commands:
$ mkdir namer $ cd namer
Put this text into a file called polyorb.conf in the namer directory:
[iiop] polyorb.protocols.iiop.default_port=9099
You can use any port you want, just pick one that's not being used by something else. Numbers in the range 1025 .. 65535 are valid. This number should be fine for this test. Then run this command (you should still be in the namer directory):
$ po_cos_naming
That will print out two long environment variable declarations, then sit and wait. Copy the value (but not the name) of the shorter one (the one called POLYORB_CORBA_NAME_SERVICE) and put it in place of the similar string (the corbaloc part) in the text below. Change the port number (the number after the ”:”) to the one we used above; the rest should be kept as printed by the command. Put the revised text into a file called polyorb.conf (a different one than the polyorb.conf we created above in the namer subdir; this one goes wherever you run the client and server commands from):
[dsa] name_service=corbaloc:iiop:1.2@192.168.1.1:9099/NameService/000000024fF0000000080000000 [iiop] polyorb.protocols.iiop.default_port=5001
Again, the port number used by the client and server (the 5001 in the fourth line) is up to you, but this value should work for this test.
Now open two more terminal windows. In one, run this command:
$ bin/server_partition
That should start the server, which should sit and wait for connections from clients. You may note that the namer window printed out a bunch of text when the server started; this is to be expected, and can be ignored.
In the second new terminal, run this command:
$ bin/client_partition
That should start the client, which should connect to the server and start printing out the server's greeting message.
Congratulations, you've gotten DSA running!
Wide Area Net Test
In Brief
- adjust /etc/hosts:
- open ports:
- Run-time configuration: (polyorb.conf)
- start po_cos_naming:
- start Server:
- start Client:
Detailed To be done