The Akula synchronization mechanism lets you synchronize changes to the data in the persistent data store with the back end data source. If the client app modifies data in the persistent data store, the synchronization mechanism can upload those changes to the app scope. In response to the upload, the app scope returns to the client any updates to the data since the client performed the last synchronization and automatically updates the data in the persistent data store.
This section contains the following topics:
Server interaction overview
Synchronization relies on the Akula persistence mechanism. This mechanism uses the persistence manager to store data for the client on the client device. Simple client persistence looks like the following:
In a simple persistence case, the client app calls methods on the persistence manager, and the persistence manager adds, removes, or gets data from the persistence data store. It returns data to the client app when necessary. The data in the persistent data store stays on the device even after the client app is exited or the client device is shut down.
Synchronization ensures that the client app's persistence data store matches (or stays in sync with) the data on a remote server. In this case, the client app uses the Persistence Manager to communicate with a remote server in addition to its own persistent data store. A simple synchronization request looks like the following:
In a simple synchronization case, the client app calls methods on the persistence manager, and the persistence manager manages the data between the persistence data store and the remote data store. The Akula Server accepts requests from the client device that contain updates to send to the back end data store. The server also sends a response to the client device that contains updates from the back end data store.
As a result of a sync operation, the data in the persistent data store should match the back end data store, whether new data was entered on the client to its own persistent data store or by another client to the back end data store.
The synchronization process
The following image shows the synchronization process:
To work with the synchronization mechanism:
The Akula synchronization mechanism adds meta information about the data to the persistent data store to manage the sync. Do not use any other mechanism to download data from the Akula Server if you want that data to be controlled by the synchronization mechanism.
During sync operations, the persistent data store is locked. Do not attempt to access it until the sync operation completes.
- After the initial data sync, use the persistence manager to get, update, and delete data in the persistent data store. You can also add new data objects to the persistent data store. You use the same process to update syncable objects as you do to update persistable objects in the persistent data store. For more information on using the persistence manager, see Storing Persistent Data on the Client.
To synchronize the local data in the persistent data store with the data on the Akula Server, use the persistence manager to execute a sync operation. The sync operation automatically uploads any modifications to the data from the persistent data store, including any modified and deleted data objects and any new data objects.
On the Akula Server side, the app scope uses the Sync module to handle the sync data sent up from the client. The module is responsible for updating any modified and new data objects in the back end data store, and for resolving any conflicts caused by multiple clients updating the same data. You can also write a custom module that performs more complex synchronization actions. For more information, see Writing a Custom Sync Module.
The Sync module also returns a response object to the client that contains any updates to the previously downloaded data. This response is handled automatically by the client to update the data in the persistent data store. If there are no data updates sent up from the client, the client still receives a response containing the server updates.
After the sync, you should assume that all in-memory syncable objects are no longer valid and must be read again from the persistent data store before being used on the client.
Full and incremental sync operations
The Akula synchronization mechanism lets you perform two types of sync operations:
- Full sync - Upload any modifications from the persistent data store on the client to the server, including any modified and deleted data objects and any new data objects. The server then updates any modified and new data objects in the back end data store, and resolves any conflicts caused by multiple clients updating the same data.
In response, the Akula Server sends a completely new set of records back to the client, overwriting all data in the persistent data store. The new set of records contains any changes included in the upload from the client.
- Incremental sync - Upload any modifications from the persistent data store on the client to the server, just as for the full sync. The server then updates any modified and new data objects in the back end data store, and resolves any conflicts, just as it does for a full sync.
In response, the Akula Server only sends to the client changes to the records, including records added, update and deleted on the server since the last sync. If this is the first time you have performed a sync, then the response is the same as for a full sync.
Notice that for both sync types, the client uploads its modifications from the persistent data store to the server. The two sync types differ only in the response returned from the server. On the client side, your action after either type of sync is the same – you should assume that all in-memory syncable objects are no longer valid and must be read again from the persistent data store before being used on the client.
- If the client requests a full sync, then the server must respond with a full sync.
- If the client requests an incremental sync, then the server can return either an incremental or a full sync as determined by the server.
Creating synchronizable classes
On native clients, your object model must implement the AKModel interface (Android) or AKModel protocol (iOS) to be compatible with both the persistence mechanism and the synchronization mechanism. To simplify the process of syncing data, Akula provides a simple concrete implementation of AKModel called AKBasicModel, which you can extend, rather than implementing AKModel on your own.
For more information, see Modelling Data for Persistence.
About server and local keys
All objects compatible with the Akula synchronization mechanism contain property/value pairs and a single key value, called the local key, that is unique to every instance of the model.
Because every model has a unique key, you can use the persistence manager's
objectOfType:forLocalKey:method (iOS) to retrieve a model from the persistent data store. If you do not know the value of the local key, you can retrieve all objects of a specific type, or write a SQL WHERE clause to retrieve objects from the persistent data store. For more information, see Storing Persistent Data on the Client.
After a full sync, all local keys for the records in the persistent data store are regenerated and therefore have a new value. Therefore, after a full sync, use the following methods to access records in the persistent data store:
On the server side, the server might store the model object in a database. Typically, data written to a database requires a property that contains the primary key used by the database to uniquely identify each record.
If you use the synchronization mechanism to download objects from the server or upload objects to the server, those objects must contain a primary key property. You must define a corresponding field in your client-side model for the primary key. For example, your client app wants to download objects that contain customer information from a back-end data source. The back-end data source contains three properties for each customer:
custid, and uses the
custid property as the primary key.
To represent customers in your client app, for example, create a Customer class that defines three properties named
custid. When you perform a sync, the server downloads all Customer objects. Because the data is coming from the server, the
custid property corresponding to the primary key contains a value.
However, when you add a new object on the client of type Customer, you must determine how to set the value of the server's primary key for the new object. Typically, you have two options:
- If the server sets the value of the primary key field when you upload the data, then leave the primary key property empty. The server then sets the value of the key field when you upload the data on the next sync.
- If the client sets the value of the key field, then set its value in the object before writing the object to the persistent data store.
For either option, you must include the server's primary key in the schema of the model when you initialize the persistent data store.
Using a client rule to block sync
In an environment where you have many clients, you might want to restrict when the client can perform a sync. For example, you might prevent sync during times of heavy network usage. Or, because a sync can potentially require a large amount of data to be sent from or to the device, you might restrict sync to only be allowed when the device has a WiFi connection.
Sync rules let you block a client app from performing a sync operation the following conditions:
- Battery charge level
- Type of network connection
- Time of day
For more information on client rules, including the sync rules, see Applying Sync Rules.