TAO_Implementation_Repository 2.0.4
|
In order for a server to make use of the Implementation Repository, it must communicate with the ImR to keep it up to date on such things as the server's running status. These functions now are contained within the POA, so when a Persistent POA is used on a server that has -ORBUseImR specified, it will communicate with an Implementation Repository, if one is available.
The new ImR is based on the ImR in TAO 1.2.2 with added features to help improve throughput and load balancing. The work to be performed by the Implementation Repository is distributed between two entities (ImplRepo_Service and ImR_Activator) to help achieve the goal of better throughput and load balance.
The ImplRepo_Service acts as the main server which is visible to the application intending to use the ImR. It receives requests sent via tao_ImR and distributes the work to the registered ImR_Activators. It is stateless and does not maintain any information except about the ImR_Activators that are registered with it. Its job is to act as a mediator between the application and the actual ImR_Activator that does the real work. As of now, we only support one ImplRepo_Service to be running at any time. ImplRepo_Service can be reached through the usual methods of -ORBInitRef and -ORBDefaultInitRef and multicast.
Commandline Arguments that can be passed to ImplRepo_Service
-d debug information -m support multicast discovery. -o generate the ior. -x support persistence to the ImplRepo_Service. We use XML to support persistence. Names of the activators registered with the locator, their IORs, and the servers registered with each of the activators are saved to the xml file. Use this option to pass the name of the file where the data has to be saved.
And, ofcourse, the ORB Options.
ImR_Activators, as you might have guessed, do the real work of activating servers or shutting them down and maintaining the information about servers related to them. Only one instance of an ImR_Activator can be run on one host. The ImR_Activator is not exposed at all to the application. Only the ImplRepo_Service needs to and it is the only one that can contact the ImR_Activator.
An instance of ImR_Activator first registers itself with the ImplRepo_Service so that it can begin to receive requests. When registering with the ImplRepo_Service, it passes the hostname where it is being run and its IOR to the ImplRepo_Service. And, the ImplRepo_Service reaches it using the same information.
The Commandline paramters that are valid for ImR_Activator are
-c: Run the Service command. -d:number Debug Information -l lock the database. -o Generate the IOR to a file (just in case some one wants to read the IOR) -r Enable Win32 regsitry implementation. -s Run as a service. -t Set a timeout value. -h Prints the help.
When Persistence of an ImR_Activator is required, we will save the information about the server's that this ImR_Activator is related to in a file (being the easy form of a persistent database). The information about each server include its startup options, location, working directory which are needed to execute the requests that can passed by tao_imr with regards to the server.
There are two ways in which you can store data in the file. One way is to use ACE_Configuration_Heap to save all the information to the file. To do this, we have to pass the '-p' option.
-p Pass the ImplRepo service a filename to use for the backing store. Uses ACE_Configuration_Heap.
The second way is to save in XML-ized format.
-x Pass the filename where the repository information should be saved. Use XML format.
The first thing to do is to have an ImplRepo_Service running. Once the ImplRepo_Service is running, we can instantiate one or more ImR_Activators as needed per the application. As mentioned already, the ImR_Activators, upon instantiation, register with the ImplRepo_Service to be able to receive requests.
When a new server has to be added or any change has to the done to an existing server, a request is to be sent to the ImplRepo_Service via the tao_imr utility. Startup commands, the working directory, the host where the server should be started up and such other information are passed to the ImplRepo_Service via the TAO_ImR commandline arguments.
If the host where the server should be started up is passed while adding a new server, the ImplRepo_Service chooses the ImR_Activator that is running on that host to be responsible for the server's activities. Otherwise, an ImR_Activator is chosen based on the Round robin algorithm. We plan to use better algorithms based on the existing load for the same purpose in future. Whatever way the ImR_Activator is chosen for a server, once an ImR_Activator is chosen, that ImR_Activator remains reponsible for the server throughout the server's lifetime.
After an ImR_Activator is chosen, the ImplRepo_Service passes the request to the chosen ImR_Activator. The ImR_Activator acts on the request and updates its database to reflect the new state of the server.
ImplRepo_Service -o locator.ior
Run the Activator Example:
ImR_Activator -ORBInitRef ImplRepoService=file://locator.ior
The main steps for the lifetime of a server that uses the ImR are generally the following:
tao_ImR -ORBInitRef ImplRepoService=file://locator.ior add plane -c "airplane_server -i -ORBInitRef ImplRepoService=file://locator.ior"
tao_ImR -ORBInitRef ImplRepoService=file://locator.ior shutdown plane
tao_ImR -ORBInitRef ImplRepoService=file://locator.ior remove plane
As of TAO 1.0.9, the Implementation Repository support on the server-side has been integrated into the POA. Previously, the IR_Helper class needed to be used explicitly. Now only the "-ORBUseImR 1" command line argument needs to be used.
There are a couple of restrictions on the server though. Only objects within a persistent POA will be supported by the ImR. Also the Implementation Repository will key its entries on POA name. What this means for the server is that each server must have unique persistent POA names.
As mentioned in the INS documentation (in TAO/docs/INS.html), a base IOR can be passed to the ORB. Then when resolve_initial_reference is called, the ORB can append the service name to the base IOR to form a full IOR.
When used with the ImR, this can be a powerful feature. If the ImR's endpoint is used as the base IOR, then the ImR can be used to provide many services via the resolve_initial_reference functionality.
For example, let's say the ImR service is running on doriath on port 5555 and the Name Service is already registered with the ImR (in that the ImR knows how to start the Name Service).
Now we should be able to run some client that uses the Name Service like this:
client -ORBDefaultInitRef corbaloc:iiop:doriath:5555/
When the client calls resolve_initial_reference("NameService"), the ORB will resolve that to "corbaloc:iiop:doriath:5555/NameService". The ImR recognizes this IOR as a pointer to the NameService, and will then start it up if necessary. Finally, it will forward the client to the Name Service.
Services used in this way have two requirements:
Each server can have one of three different types of activation modes:
First, some background.
For the longest time, there was no way with TAO's Implementation Repository to register a server and then start using the client immediately. The server had to be started once just for the purpose of creating an IOR for the client to use. The problem was that it was very difficult to create an IOR without running the server.
It would be nice to be able to generate a valid IOR without requiring the program to be run. A valid IOR in this case requires two major things. First it requires the endpoint of the ImR. This is relatively easy to get, since it is encoded in the ImR's IOR. Second it also requires an object key. At the least, this involves both the POA hierarchy and the object name.
So if we knew the POA and object names, then we should be able to create an IOR for the server. One possibility would be to have tao_ImR ask for both the POA and the object, and then create the POA hierarchy to generate an IOR. Doing the generation is this manner (letting the POA create the reference) shields us from changes in the IOR generation schemes. Since we are using the same code that the server would use, our IORs would be up to date.
It ends up there is an easier way to do this. The Interoperable Naming Service is intended to be used in situations where an IOR could be created by hand. Using the same information as above, it is not difficult to take the endpoint information from the ImR and attach the POA name. For example, let's say that we are running the ImR on ringil.ece.uci.edu at port 5000. The endpoint would be "corbaloc:iiop:1.2@ringil.ece.uci.edu:5000". If we are creating an IOR for the nestea server, we'd just need to attach "/nestea_server" to the end of the endpoint. Now we have an IOR.
So what does this mean for the server?
The main issue here is that the server must be changed to support the simplified name. This can be done by using the IORTable like this:
CORBA::Object_var table_object = this->orb_->resolve_initial_references ("IORTable", ACE_TRY_ENV); ACE_TRY_CHECK;
IORTable::Table_var adapter = IORTable::Table::_narrow (table_object.in (), ACE_TRY_ENV); ACE_TRY_CHECK; if (CORBA::is_nil (adapter.in ())) { ACE_ERROR ((LM_ERROR, "Nil IORTable\n")); } else { adapter->bind (poa_name, server_str.in (), ACE_TRY_ENV); ACE_TRY_CHECK; }
These lines, as taken from the nestea_server example, just uses the same poa_name as registered with the ImR and associates it with the server_obj object in the IOR table. Because the ImR will be able to handle the simplified name (if it uses the POA name scheme) then this IOR will work.
Just one more thing, each object that needs an IOR needs to be registered with the IOR table. But this raises the problem of uniqueness; they all can't have the same name. The ImR will actually only look at the name part of the simplified IOR up to the first "/". So both "corbaloc:iiop:1.2:5000/nestea_server/foo" and "corbaloc:iiop:1.2:5000/nestea_server/bar" will be treated by the ImR as objects in the "nestea_server" server.
Tao's Implementation Repository can be made persistent by doing two things:
Always start up the Implementation Repository on the same port. This ensures that the Implementation Repository will not have to re-ImR-ify the IORs of every server registered to it each time it starts up. The way to accomplish this is to add
-ORBEndpoint iiop://(hostname):(portnumber)
to the ImR_Activator's startup command line. The host name can be obtained portably in C++ code with the lines
ACE_INET_addr ad;
char *hostname = ad.get_host_name ();
or in a Perl script by adding
use Sys::Hostname;
$hostname = hostname();
There are even specific port numbers, assigned to the OMG by the IANA, which can be used for this purpose. They are 683 (for IIOP) and 684 (for IIOP over SSL). For more information about this, see http://www.iana.org/ and http://www.isi.edu/in-notes/iana/assignments/port-numbers.
Pass the ImR a filename to use for the backing store, specified by the command line option
-p (filename)
This option must be used the first and every subsequent time the persistent ImR is started up.