Differences

This shows you the differences between two versions of the page.

Link to this comparison view

a_dsa_tutorial [2012/01/05 19:37] (current)
thomaslocke created
Line 1: Line 1:
 +===== 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: 
 +
 +  * [[http://​adaic.org/​standards/​05rm/​html/​RM-E.html|Ada 2005 Reference Manual, Annex E]]
 +  * [[http://​www.adahome.com/​rm95/​rm9x-E.html|Ada 95 Reference Manual, Annex E]]
 +  * [[http://​www.adahome.com/​LRM/​95/​Rationale/​rat95html/​rat95-p3-e.html|Ada 95 Rationale on Distributes Systems]]
 +
 +===== Annex E: Distributed Systems =====
 +
 +The [[http://​adaic.org/​standards/​05rm/​html/​RM-E.html|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//​.
 +
 +<code ada>
 +package Server is
 +   ​pragma remote_call_Interface;​
 +   ​function Greeting return String;
 +end Server;
 +</​code>​
 +
 +Copy the following into a file called //​server.adb//​.
 +
 +<code ada>
 +package body Server is
 +   ​function Greeting return String is
 +   begin
 +      return "​Greetings,​ Earthling.";​
 +   end;
 +end Server;
 +</​code>​
 +
 +**Client:**
 +
 +Copy the following into a file called //​client.ads//​.
 +
 +<code ada>
 +package Client is
 +   ​procedure Start; ​
 +end Client;
 +</​code>​
 +
 +Copy the following into a file called //​client.adb//​.
 + 
 +<code ada>
 +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;
 +</​code>​
 +
 +**Applets:​**
 +
 +Copy the following into a file called //​start_server.adb//​.
 +
 +<code ada>
 +with Client;
 +with Server;
 +procedure start_Server is
 +begin
 +   loop
 +      delay 0.5;
 +   end loop;
 +end;
 +</​code>​
 +
 +Copy the following into a file called //​start_client.adb//​.
 +
 +<code ada>
 +with Client;
 +procedure start_Client is
 +begin
 +   ​Client.start;​
 +end;
 +</​code>​
 +
 +===== Preparation =====
 +
 +Of course, we need an Ada compiler and DSA implementation. A good choice might be the Gnat and Polyorb (GPL11) versions available at [[http://​libre.adacore.com/​libre/​|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//​.
 +
 +<code ada>
 +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;
 +</​code>​
 +
 +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**
  

Navigation