Distribution of the Trom application

In previous lessons we have already split our Trom application into multiple objects and learned how distribution is handled within applications.

In this lesson we are going to merge these 2 notions and distribute our Trom application.

Initial application design

In the 'improved' application design, the application logic is decomposed into meaningful objects and each of them is associated with the appropriate behavior.

As a reminder, these objects are :

  • The People object manages the information related to the people willing to use the metro. The Customer and Destination bags are attached to it.
  • The Metro object deals with the structure of our metro network and is responsible for the Connection bag.
  • In addition the Supervision object traces the results of the application and stored the travels made by of the customers in the Travel bag.

So far, the application is running locally : on a generic domain of localhost (local machine).

Distribution of the application

Most of the time, the distribution of an application is required by system component design constraints or in order to divide the working load of the application among several different machines.

In the following, we will demonstrate 2 distribution schemes that may cover most (if not all) of the distribution use cases:

  • First, the application is distributed on a cluster of machines sharing a common file system on which the middleware binaries and the application are installed.
  • Then, the application will be distributed over two separate domains without anything in common (neither domain names, nor installation directories).

Even if the first solution is preferred in the case of a shared installation of the middleware (let's say via NFS), we will see that the deployment of a distributed application over multiple separate domains remains quite easy. If the network topology allows both types of distribution schemes, switching from one implementation to the other is literally a question of minutes.

The source code included as an example for the present lesson relates to the second solution.

Distribution over two machines in the same domain

We assume that we can access two machines, h1 and h2, belonging to the same domain named cea.com, and sharing the middleware binaries in the common /Shared/cea/middleware_install/src/middleware/.

The application code is stored in the directory /Shared/cea/workspace/middleware/tutorials/trom_07 which is also shared by the two machines.

The quinoa.py file should reflect this topology with:

  • one common domain
  • one shared installation of the middleware (attached to the domain)
  • two distinct machines.

In the distribution example, the quinoa.py file is adapted to make the Supervision object run on a separate host (here : h2.cea.com). Since the domain name and the middleware's installation shared directory are the same for all the hosts, only one unique domain description is required.

 # ----- Physical Distributed System
 # ----- Domain
 Domain1 = data.DomainDescription()
 Domain1.name = "cea.com"                             <------ adapt to your system
 Domain1.bin_directory = "/Shared/cea/middleware_install/src/middleware/"      <---- adapt
 Domain1.var_directory = "/tmp"                                           <---- adapt
 Domain1.type = "cluster"

 # ----- Machines
 H1 = data.HostDescription()
 H1.domain = Domain1
 H1.name = "h1"                                          <------ adapt to your system

 H2 = data.HostDescription()
 H2.domain = Domain1
 H2.name = "h2"                                          <------ adapt to your system

Once the common domain and the two hosts are declared, distributing the Supervision object over the h2 host becomes as simple as assigning H2 to the host property of the object!

 SupervisionObject = data.ObjectDescription()
 SupervisionObject.name = "Supervision"
 SupervisionObject.type = "Coordinator"
 SupervisionObject.port = None
 SupervisionObject.host = H2                             <------ only change that
 SupervisionObject.application = A1
 SupervisionObject.nameserver = NameServer
 SupervisionObject.params = {param.OBJECT_TRACE_LEVEL:TRACE_LEVEL}
 SupervisionObject.list_of_bags = [bag4]
 LIST_OF_OBJECTS.append(SupervisionObject)

While the application is launched with the classical following command, the system will automatically start the objects on their respective hosts.

python quinoa.py --start_objects All --run_scripts All

The application is launched and produces the same results as in the previous lessons. Isn't that what we call "transparency"?

Using the monitor, you can witness the behavior of the distributed application and the location of the objects. As the NameServer of the application is hosted on the h1 host, simply call the following URL :

http://h1.cea.com:9999/NameServer/MONITOR

Indeed, if you navigate to the Supervision object, you may notice that the URL displayed in the address bar of your browser refers to h2.cea.com, the other machine. But, once again, it is totally transparent for the user, since the monitor facilities are directly embedded at the object level (object container to be precise). Then, the browser interface switches silently from one object to the other, aggregating information automatically.

Distribution over two machines in different domains

Now, we complicate the context a bit and we assume that we want to distribute our application across two different domains cea.com and intra.cea.fr.

The application code is stored in the /home/cea/workspace/tutorial/trom_07 directory on the first domain, and in /usr/middleware/applications/trom_07 for the second domain.

Please, note that the principles described here remain valid in case of two hosts sharing the same domain name (ex. cea.com), but no common installation directories (i.e. each host houses its own installation directory).

The application will be launched on the machine of the first domain.

You have to modify your quinoa.py file in the following manner,

 # ----- Domain
 Domain1 = data.DomainDescription()
 Domain1.name = "cea.com"                             <------ adapt to your system
 Domain1.bin_directory = "/home/cea/middleware_install/src/middleware/"      <---- adapt
 Domain1.var_directory = "/tmp"                                           <---- adapt
 Domain1.type = "my local machine"

 # ----- Machines
 H1 = data.HostDescription()
 H1.domain = Domain1
 H1.name = "h1"                                          <------ adapt to your system

 # ----- Domain
 Domain2 = data.DomainDescription()
 Domain2.name = "intra.cea.fr"                           <------ adapt to your system
 Domain2.bin_directory = "/usr/middleware_install/src/middleware/"                <---- adapt
 Domain2.var_directory = "/tmp"                                           <---- adapt
 Domain2.type = "my remote machine"

 # ----- Machines
 H2 = data.HostDescription()
 H2.domain = Domain2
 H2.name = "h2"                                          <------ adapt to your system

In most of the simplest cases, the previous definitions are sufficient : the scripts are compiled locally (inside the host from where the application is launched) then sent to the remote objects where they are enacted.

But, if the scripts integrate some statements such as COMPUTE or ASSERT, the associated libraries need to be found and be available for the remote objects.

As a consequence, the directories in which the scripts are stored, on each domain, should be added in the path property of the application description :

 # ----- Application
 A1 = data.ApplicationDescription()
 A1.name = "trom_07"
 A1.path = ["/home/cea/workspace/tutorial/trom_07", "/usr/middleware/applications/trom_07"]

The rest of the quinoa.py file remains the same as in the previous configuration.

If you launch the application in the usual way, your local machine will launch the objects through the network using the two different machines:

python quinoa.py --start_objects All --run_scripts All

Using the monitor, you can verify that the objects are running on the two different machines and that the scripts are enacted as intended.

http://h1.cea.com:9999/NameServer/MONITOR

Here again, once the application is configured accordingly, the distribution of the application is performed transparently.

Set up a test environment

This paragraph gives you complementary guidelines to test the distribtion of the Trom application over 2 machines. The second case, with distincts domains, is used for this example.

Update your /etc/hosts file, on both machines, and add the following lines (adapt IP addresses according to your network configuration) :

12.34.56.78 h1 h1.middleware_domain.com
12.34.56.79 h2 h2.otherdomain.com

Make sure that both machines can access the other one (firewall) through ping, http, ssh,...

Install the middleware on both machines.

In the quinoa.py, you need to adapt the domain definitions (intallation path, demon login, etc....), especially if the middleware is installed on both machines for different users.

Within the present tutorial, we recommend launching the middleware's bootstrap servers manually (and locally) on both machines (see lesson 07).

Launch the application as usual and enjoy !