OpenMRS Sync 2.0 resolving conflicts with synchronizing the same object

Hi everyone,

together with @dserkowski we working at OpenMRS Sync 2.0 project. More information about that: https://wiki.openmrs.org/display/projects/Sync+2.0 . The Sync 2.0 MVP (Patient synchronization) already works. There is an issue with patient conflicts and we would like to ask OpenMRS Community if the solution already exists.

To illustrate the problem look into the following link: https://wiki.openmrs.org/display/projects/Sync+2.0+Demo+Environment

  1. Imagine a situation when the Patient is created/registered in the clinic Sync2 on Monday and Sync3 on Tuesday. The data synchronization is set at three-day intervals. The data will be pushed at the same time. Assume that the Patient identifiers are set as Personal ID Number. Merging patients will fail with the message “The patient with the given Patient Identifier already exists”.

Is there implemented the solution for this issue?

  1. The patient was created on the Sync2 instance. Synchronization will success and on the Sync1, Sync2, Sync3, and Sync4 the same patient appears. Synchronization interval is set to 3 days. Clinic Sync2 update patient’s address, clinic Sync3 another information of this patient. During second synchronization one update will be overridden by another. (Patient on the parent instance Sync1 will be updated by Sync2, the next updated patient on Sync1 will be overridden by Sync3 update). Any thoughts how we can resolve this with the current core? Every object has ‘updated date’, but I didn’t find a possibility to check single field updated date.

Maybe you had a similar problem and a solution for this? Or any thoughts?

Thanks in advance!

cc: @raff, @mseaton, @darius, @dkayiwa, @pgesek, @jslawinski, @dserkowski

My take on the two issues would be as follows.

  1. See https://github.com/openmrs/openmrs-core/blob/6b43e64e91501308a7cc2656adbc78d2c6280db3/api/src/main/java/org/openmrs/api/PatientService.java#L550 if it works for you.

Before calling this method you will need to persist the upstream patient by putting a temporary identifier instead of the conflicting one on the origin patient. Also you will always want to save the upstream patient as preferred so that you do not have to resolve the same conflict with every sync (assuming you use UUIDs for matching).

  1. We do not force voiding properties of a person and creating new ones when editing… It would be easier to solve that way.

However, you will not have a collision when modifying an address on one server and an attribute on the other.

If name/address/attribute is modified at the same time on both servers, you can check its date changed and pick the latest. You don’t want to simply overwrite it though, but save the older one as voided so that there’s a track of record.

I also think it would be good to highlight that kind of automated resolution on a patient dashboard to be verified by a user e.g. when seeing the patient again or at least highlight such conflicts in a sync log for the admin.

In this approach it is very important to verify time is set the same on both servers and I think the sync2 module should do that on every sync and warn the admin, if it is not.