.. _gaiasky-master-slave:

Connecting Gaia Sky instances
=============================

Gaia Sky offers a method to connect different instances together so that their 
internal state is synchronized. The model uses a **primary-replica** 
scenario, where one (and only one) instance acts as a primary and one or
more instances act as replicas, getting their internal states updated over
a network. The user interacts with the primary instance and all replicas are updated accordingly.

.. contents::
  :backlinks: none

.. note:: In this section we use the words 'primary' and 'master' interchangeably to refer to the main Gaia Sky instance that controls the rest. We also use the words 'slave' and 'replica' to describe the instances that are controlled by the primary.

This section describes only how to configure the primary and the replica instances in order
to connect them together. This method is used to provide multi-projector rendering support
(i.e. planetarium domes), but extra steps are needed in order to configure the
orientation, distortion warp and blend settings for each replica instance.

The various instances are connected using the :ref:`REST API server <rest-server>` feature of Gaia Sky.

.. hint:: Multi-projector configuration is covered in the :ref:`"Planetarium mode multi-projector setup" section <planetarium-multi-projector>`.

Configuration
-------------

The configuration is easy and painless. You will need to launch each instance of
Gaia Sky using a different configuration file (``config.yaml``). You can
run Gaia Sky with a specific configuration file by using the ``-p`` or ``--properties``
command line flags:

.. code:: console

    $  gaiasky -p ~/.config/gaiasky/config.primary.yaml


The next sections explain how to configure the primary and the replica instances.


Configuration: replica instance(s)
----------------------------------

You can have as many replica instances as you want, but here we'll explain the process
of setting up two replicas.

1.  Copy the current ``config.yaml`` file in your config folder (see :ref:`folders <folders>`)
    into ``config.replica0.yaml``. The name is irrelevant, but choose something meaningful. 
    Repeat with ``config.replica1.yaml``.
2.  Set the property ``program::net::slave::active: true`` in each file and make sure that ``program::net::master::active`` is set
    to ``false``. 
3.  Set the desired port to listen to in ``program::net::restPort``. For example, to use the port 13900 just set the property ``program::net::restPort: 13900``. Use a different port for each replica (i.e. replica 0 listens to 13900, slave 1 listens to 13901, etc.). For example, to set up a replica in port 13900, make sure that the following lines are in its configuration file:

.. code-block:: yaml

    program:
        net:
            restPort: 13900
            master:
                active: false
            slave:
                active: true

**The replica instances should be launched before the primary**. Launch the replica(s) with:

.. code:: console

    $  # Launch replica 0
    $  gaiasky -p /path/to/config.replica0.yaml
    $  # Launch replica 1
    $  gaiasky -p /path/to/config.replica1.yaml


Once the replica(s) have been launched, you can verify that the API is working by
visiting ``http://localhost:13900/api/help`` with your browser. 
Modify the port with whatever port you are using.

.. hint:: Only the primary instance is starting the scripting server. The replicas are automatically forbidden to do so!

Configuration: primary instance
-------------------------------

Copy the current ``config.yaml`` file into ``config.primary.yaml`` and 
edit the following lines.

1.  Set the property ``progra::net::master::active: true`` and make sure that ``program::net::slave::active`` is set to ``false``.
2.  Add the locations of all desired replicas under the settings ``program::net::master::slaves: [URL1, URL2, ...]``.


For example, in order to connect the primary with two replicas, both running locally (``localhost``) on ports 13900 and 13901, add the following to the ``config.primary.yaml`` file:

.. code-block:: yaml

    program:
        net:
            restPort: 13900
            master:
                active: true
                slaves: [http://localhost:13900/api/,http://localhost:13901/api/]
            slave:
                active: false


Then, just launch the primary (**after the replicas are running!**):

.. code:: console

    $  gaiasky -p /path/to/config.primary.yaml



Caveats
-------

Even though this offers a very flexible system to connect several instances of Gaia Sky
together, each instance is a fully-fledged application with its own copy of 
the scene graph and the data structures. 
This means that, if you run them locally, the data and scene graph will
be replicated several times in memory, possibly consuming lots of gigabytes. 

Handle it with care.