GNU Health/Synchronization Guide
This chapter applies only to version 2.8 of GNU Health.
||Deprecation warning. The current synchronization system is deprecated. It will be replaced by the GNU Health Federation model, starting in GNU Health 3.2|
Scope of this Document
This guide tries to cover the synchronization process among GNU Health instances and their relation to the central instance. The intended audience are project managers and system administrators. It's quite general, and avoids getting too technical, although some topics and tasks require knowlegde of operating systems, networking, database administration and Python programming.
- GNU Health instance: Stand-alone GNU Health installation. It contains the database, the Tryton kernel and, at least, the core health module.
- Satellite instance: Each GNU Health instance that is part of the synchronization.
- Central Instance: The main GNU Health instance (at the Ministry of Health, for example). This is the instance that contains the aggregated information, and gets the synchronization requests from the satellite instances.
- RabbitMQ: The message broker. It is executed at the operating system and run as a daemon.
- Celery: The asynchronous task / job manager used by Tryton. It uses RabbitMQ as the middleware. The tasks for synchronization are periodically lauched from the operating system at a pre-defined fixed interval.
Installation of Satellites and Central instance
Install RabbitMQ messaging system server:
# pkg install rabbitmq
Install Celery-tryton (locally, with "gnuhealth" server Operating System user). It will install Celery as a dependency.
From GNU Health v2.6, the PYTHONPATH variable is included in the user environment.
$ pip install --user "celery_tryton"
Download the latest tryton_synchronization module:
$ hg clone http://hg.b2ck.com/tryton_synchronisation
Note: You use hg clone the first time only. Afterwards, use the hg pull and update commands.
Install the Tryton synchronisation package for Satellites:
$ cd tryton_synchronisation $ python ./setup.py install --user
$ pip install --user "proteus==3.8"
Add the synchronisation_id and synchronisation_url to trytond.conf:
synchronisation_id = the_id_of_your_satellite_instance synchronisation_url = http://user:firstname.lastname@example.org:7500/name_of_the_central_instance_database
Note: Replace user:password by the actual login credentials.
Running the Synchronization Engine on Satellite Instances
(Notes taken from FreeBSD. The specifics vary from operating systems)
1) Start Rabbit-mq service
# service rabbitmq onestart
2) Create a configuration file celeryconfig.py with the following entries
TRYTON_DATABASE = "name_of_your_satellite_instance" TRYTON_CONFIG = "/home/gnuhealth/gnuhealth/tryton/server/config/trytond.conf"
This celeryconfig.py file should be stored in a place available in $PYTHONPATH. Let's use /home/gnuhealth/gnuhealth/tryton/server/config (which is the same value as $PYTHONPATH).
3) Create your customized health_synchro module
You need to specify which type of synchronization you want for your instance. We have included a synchro module template in the documentation folder ($HOME/gnuhealth/doc/samples). You can copy and link this module into your local modules directory and customize it to fit your needs.
cdmods cd local cp -a $HOME/gnuhealth/doc/samples/health_synchro . ln -si $HOME/gnuhealth/tryton/server/modules/local/health_synchro $PYTHONPATH/trytond/modules
4) Start the Tryton GNU Health instance
$ cdexe $ ./trytond
5) Start Celery Broker
~/.local/bin $ ./celery --app=celery_synchronisation worker --config=celeryconfig
6) Execute the tasks
./celery call celery_synchronisation.synchronise_new --config=celeryconfig
./celery call celery_synchronisation.synchronise_pull_all --config=celeryconfig
./celery call celery_synchronisation.synchronise_push_all --config=celeryconfig
This tasks will be called from a cron job. You can adjust the period to best fit your needs.
Note: This documentation is mainly taken from B2CK original document on the Tryton synchronization.
Each server instance has a unique ID (`synchronisation_id`) set in the configuration file.
A Celery instance provides three main tasks:
- synchronise_push_all: Pushes to the main server all the instances modified since its last synchronization.
- synchronise_pull_all: Pulls all the known instances that have changed on the main server.
- synchronise_new: Fetch all the non-synchronized instances from the main server.
The tasks communicate with the main server using the XML-RPC protocol defined by synchronisation_url in the configuration file. "celery_synchronisation" uses "celery_tryton" to integrate with Celery.
Developers "Mini-Guide" to the Synchronization Engine
The health_synchro module contains some of the following classes.
There are two main models used to synchronize records from objects.
- SyncMixin: Synchronises using an existing unique key on the model.
- SyncUUIDMixin: It uses a Universal Unique Identifier (UUID) on each record.
If the model has a unique code, then we should use the SyncMixin method to synchronize the records. A good example for SyncMixin would be the gnuhealth.patient or the party.party models. Both have a unique id attribute (field) and this is the field that will be used by the syncronisation engine.
Example of SyncMixin use:
class Party(SyncMixin): __name__ = 'party.party' __metaclass__ = PoolMeta unique_id_column = 'code'
Note that in the SyncMixin model, the unique_id_column must always be present, and assigned a field that is unique (in this case code).
This synchronization method is used for models that represent dynamic events. For example, a patient appointment:
class Appointment(SyncUUIDMixin): __name__ = 'gnuhealth.appointment' __metaclass__ = PoolMeta
Note that there is no unique_id_column on class using the SyncUUIDMixin.