Skip to end of metadata
Go to start of metadata

You are viewing an old version of this content. View the current version.

Compare with Current View Version History

Version 1 Next »

The Cavrnus system primarily consists of a set of spaces, each an individual environment a user can join, participate within, create, or modify.

The Journal

The data that defines a space is called its Journal.

The Journal consists of a linear sequence of Operations. Operations are never deleted, the journal only ever moves forward. Think of the journal as a log of everything that ever occurred within the space, which when replayed, reconstructs the space in its current state.

When connected to a space, a user can submit an Operation to be included in the journal. These become part of the permanent journal. Common operations include:

  • Instantiating objects

  • Updating property values

  • Cancelling previous operations

  • Adding a chat message

A Transient, is a communication sent by a user which is not stored in the journal. Transient communications involve either temporary or unsynchronized state changes. When a new user joins the space, they will not be transmitted any historical transient information; they only receive and process the permanent journal. Common transients include:

  • User metadata ( user entry and exit from the space, avatar position, camera position, mute state, streaming state )

  • Client to client application communications needed to synchronize certain systems.

  • Client pings to get other users attention.

  • Requests for other users to follow.

But the most important transient is most likely:

  • Operations in progress.

As an example, while a user is manipulating an object’s position, they will frequently send transient operations as they change the object’s values. When they release the object they will submit a finalized Operation. Or if they instead hit Escape or otherwise cancel, they will send a transient event cancelling the in-progress process.

Lastly, transient events are often echoed locally; they take effect immediately within the executing client’s application. Operations require guaranteed ordering, so they only ever are applied after a round trip to the Cavrnus API server. Since latency makes for bad UX, transients are applied locally immediately. The journalling system will ensure that the correct synchronized state is reached despite a potential order difference when multiple users manipulate the same fields simultaneously.

In short:

Operations are permanent changes.

Transients are temporary state transmissions and coordination systems.

An journal example:

For example, consider the following sequence of abstract operations:

  1. Create a Sphere called 'A'.

  2. Move 'A' to (10,1,0).

  3. Create a Box called 'B'.

This results in a space with two objects, A and B. If we wish to remove 'B' from the space, rather than delete anything from the journal, we instead:

4. Cancel operation #3.

Which will result in 'B' not being present, as its creation is now ignored.

Consider a user wishing to ‘Undo’ the move of 'A', operation #2. In this case, we just:

5. Cancel operation #2.

Rather than track previous location and update it, we simply mark the operation as ‘cancelled’.

Oops, now we want to redo that operation!

6. Cancel operation #5.

Now the cancellation is cancelled. Operation #2 is now live once again.

A more thorough transient example:

Consider a user ‘A' dragging a slider for ‘x' from 0, through 1, then releasing on 2. What events occur for user 'A’ and 'B’?

  1. 'A': Local transient: Update 'x' to 0

  2. 'A': Send transient: Update 'x' to 0

  3. ‘B' only: Recv and apply transient: Update 'x' to 0 (client 'A’ will ignore this update as it knows it has already been applied)

  4. 'A': Local transient: Update 'x' to 1

  5. 'A': Send transient: Update ‘x' to 1

  6. ‘B' only: Recv and apply transient: Update 'x' to 1. Client 'A’ will ignore this update as it knows it has already been applied.

  7. 'A': Local transient: Update 'x' to 2

  8. 'A': Send transient: Update ‘x' to 2

  9. ‘B' only: Recv and apply transient: Update 'x' to 1. Client 'A’ will ignore this update as it knows it has already been applied.

  10. 'A': Send operation: Update 'x' to 2, noting this operation concludes the above transient sequence

  11. ‘A' and ‘B’: Recv operation: Update ‘x' to 2, with transient conclusion. Clients will mark the transient events completed and reorder them to match the operation’s ordering, determined by the API server. In most cases, the live state will not need to be updated, as it is already correct.

  • No labels