Gem #111: The Distributed Systems Annex, Part 5 — Embedded Name Server
by Thomas Quinot —AdaCore
Let's get started...
In the first installment in this series of DSA Gems, we used an application managing a public bulletin board as a good example of a client-server design. We used the following configuration:
configuration Dist_App is pragma Starter (None); -- User starts each partition manually ServerP : Partition := (Bulletin_Board); -- RCI package Bulletin_Board is on partition ServerP ClientP : Partition := (); -- Partition ClientP has no RCI packages for ClientP'Termination use Local_Termination; -- No global termination procedure Display_Messages is in ServerP; -- Main subprogram of master partition procedure Post_Message; for ClientP'Main use Post_Message; -- Main subprogram of slave partition end Dist_App;
and we obtained two executables, one for each partition (serverp and clientp), by issuing the following command:
po_gnatdist dist_app
With the above po_gnatdist configuration, running the application requires three steps:
- Start po_cos_naming, the PolyORB name server. On startup, an object reference is displayed, which must be passed to all partitions in the environment variable POLYORB_DSA_NAME_SERVICE or through a PolyORB configuration file.
- Start serverp, the server partition, which will register its RCI package (Bulletin_Board) with the name server.
- Start clientp, the client partition, which will query the name server for the location of the RCI.
Simplifying the process
To make this whole process easier, you can instead direct po_gnatdist to embed the name server within the main partition (serverp). This is achieved by saying:
pragma Name_Server (Embedded);
in the configuration file.
You can then start serverp without an external name server: it is now included within the partition. You still need to convey the location of the name server to clients. From within the server partition, this information can be retrieved by querying the PolyORB run-time parameters:
Put_Line ("ServerP started, embedded name server is at:"); Put_Line (PolyORB.Parameters.Get_Conf ("dsa", "name_service", ""));
This outputs a string of the form:
IOR:<...long series of hex digits>
which encodes all required information. You can then start the client partition by specifying this value in the POLYORB_DSA_NAME_SERVICE environment variable. In Bourne shell syntax, this translates to:
POLYORB_DSA_NAME_SERVICE=IOR:<...> ./clientp
Using the Windows cmd shell, this would be:
set POLYORB_DSA_NAME_SERVICE=IOR:<...>
client
Passing the name server information in a file
POLYORB_DSA_NAME_SERVICE can also indicate a file name, prefixed with the string "file:". So, if you modify serverp to output the name service reference to a file "ns.txt", you can start the client using
POLYORB_NAME_SERVICE=file:ns.txt ./clientp
Using a well-known port
Note: this requires the latest development version of PolyORB.
It is sometimes inconvenient to have to transport a string value or a file from the server to the client, and to have to update it each time the server is restarted. Using appropriate PolyORB run-time configuration directives, you can force the server to listen for network connections at a fixed location.
The following configuration forces the server to listen on port 8889:
[iiop] polyorb.protocols.iiop.default_port=8889
Once this is set for the server, you can direct the client to that location by setting POLYORB_DSA_NAME_SERVICE to:
corbaloc:iiop:1.2@
The included start_server and start_client scripts provide a demonstration of this facility.
About the Author
Thomas Quinot holds an engineering degree from Télécom Paris and a PhD from Université Paris VI. The main contribution of his research work is the definition of a flexible middleware architecture aiming at interoperability across distribution models. He joined AdaCore as a Senior Software Engineer in 2003, and is responsible for the distribution technologies. He also participates in the development, maintainance and support of the GNAT compiler.