An open-source scalable personal cloud

Sync service communication

An important design decision of our reference implementation was to rely on a messaging middleware for communication. Since Personal Cloud storage services exhibit significant read-write ratios, we decided that the sync engine should support persistent client connections, push-based notifications, and asynchronous and stateless interactions. A message-oriented middleware fits well with these requirements, because of its support to loosely coupled communication among distributed components thanks to asynchronous message-passing.

The communication system must guarantee safety, speed, and above all, scalability, because the server must attend many requests. For this reason, we decided to use a message-oriented middleware called ObjectMQ. Developed at the URV, ObjectMQ is a lightweight remote object layer constructed on top of a messaging middleware compatible with AMQP. In our case, it is running on top of RabbitMQ.

ObjectMQ is using a global request queue for the SyncService, a response queue for each device (SyncService Proxy), and a fan-out Exchange for each workspace. Each device will bind its request queue to the appropriate workspace Exchange to receive notification changes in this workspace. In any case, queue message programming is abstracted thanks to ObjectMQ, so that the protocol will be defined in terms of RPCs or method calls.

In the code above we can see the interface definition of the SyncService. Clients can request the list of Workspaces they have access to with the getWorkspaces operation. Once the client obtains the list of Workspaces, it can then perform two main operations: getChanges and commitRequest. Furthermore, the client will be notified of changes by means of the event CommitEvent.

getChanges is a synchronous operation (@sync) that StackSync clients perform on startup. This is a costly operation for the SyncService as it returns the current state of a Workspace. Once the client receives this information, it registers its interest in receiving committed updates, i.e., CommitEvents (@event) for this Workspace. From that point on, any change occurring on this Workspace will be notified to the client in a push style.

commitRequest is an asynchronous operation (@async) that clients employ to inform the SyncService about detected file changes in their Workspaces. This is a costly operation since it must guarantee the consistency of data after the new changes.

CommitEvent is triggered by the SyncService in an asynchronous one-to-many operation (@event) to all out-of-sync devices in the specified Workspace. This operation is only launched by the SyncService once the changes has been correctly stored in the Metadata back-end.