Overview

This is a proposal to create a new requirement in the shared space protocol to enable offline edits and online merging.

Requirements

  1. A shared space must have a single "owner".
  2. Any member (including the owner) may perform updates on the space data.
  3. Space data changes must be synced efficiently.
  4. Members must be able to perform updates while disconnected.

Implementation

Overview

All shared space updates are currently performed as operations. The owner of the shared space will retain a list of all operations performed on the shared space data, starting with the initial request to create. These operations will be sorted by a new sequence attribute. The owner of the shared space is the only entity permitted to generate the sequence number for an operation. Members will send operations to the owner without a sequence number and the operation is not considered to be committed or accepted until the owner echoes the operation back with a sequence number. Disconnected members may apply as many uncommitted operations locally and are responsible to transmit the uncommitted operations when reconnecting to the owner. In the event of a merge conflict, the committing member will be responsible for merging.

When a member has uncommitted operations in the space and the member receives other operations from the shared space owner, the other operations must be applied before the uncommitted operations. It's the responsibility of the member that created the uncommitted operations to re-merge them after the other operations have been applied, and to retain the original operation intent.

Member Updates

Member updates performed offline may merge automatically or may require manual intervention. If intervention is required (a complex merge) a delegate/callback must be fired to the app so that the user will be presented with contextually relevant data to complete the merge. If the owner delivers operations to the member upon reconnection, the owner must apply the received operations before the uncommitted operations.

Rejected Updated

On occasion, a member update may be rejected because it's being applied to the incorrect sequence. This can happen if two members send update operations concurrently. The owner will process the first one it receives, and then reject the second one. The owner knows to reject this because all operations sent to the owner must include a apply_to attribute which indicates which sequence to apply this operation to. If the operation is rejected, the owner will send an operation rejected request to the member. It's the member's responsibility to re-apply the operation locally on the latest sequence and re-send.

Applying Updates

The member is responsible for applying operation in order. If an operation with sequence n is received, and n-1 is not the most recent operation applied, the member must queue this operation locally until the operation with sequence n-1 is applied.

Requesting Specific Operations

If a member was offline or needs a specific operation or range of operations, it can send a resend operation request to the owner. The owner will then automatically send the requested operations to the member.

New Member Joining

When a new member joins a shared space, the owner must send the new member a current full-state of the space. It's not acceptable for the owner to send all of the operations and have the member rebuild the state.

Examples