Mutable fields in Correspondence

image Correspondence is a client-side NoSQL database that synchronizes with other clients through a shared server. If you’ve experimented with the bits, there is a breaking change in the latest changeset. A new build is coming soon, as well as a closed beta of the synchronization server.

Correspondence is built on the concept of historical modeling. This is a set of theory describing historical facts with partial order. The facts have predecessor/successor relationships that define both the order in which they can consistently be applied, and the mechanism for graph traversal.

One of the core tenets of historical modeling is that facts are immutable. This makes them easy to synchronize. Fields also determine the fact’s identity. Two facts having equal fields are actually the same fact.

In many applications, it is desirable to have mutable fields. In historical modeling, you have to use the Entity Property pattern to simulate mutability. This pattern builds on the strengths of historical modeling, allowing participants to unambiguously synchronize state changes. It also has the added benefit of detecting conflicts, and allowing users and applications to resolve them. Unfortunately, this pattern can be cumbersome to apply.

The mutable keyword

A Correspondence model is defined using a language called “Factual”. The upcoming release adds three keywords to the Factual modeling language. These three keywords break a fact into sections:

  • key - Required. Contains all key fields.
  • mutable - Optional. Contains all mutable fields.
  • query - Optional. Contains all queries and predicates.

The key and query sections contain members that have always been in the language. The mutable section adds new functionality.

Fields in the mutable section are mutable. The compiler generates the Entity Property pattern on your behalf. These fields are not part of the key, since they are not actually stored within the fact itself. They are stored in successor facts that track changes.

You write this:

fact Person {
key:
    unique;

mutable:
    string name;
}

The Factual compiler generates this:

fact Person {
key:
    unique;

query:
    PersonName* nameCandidates {
        PersonName n : n.person = this
            where n.isCurrent
    }
}

fact PersonName {
key:
    Person person;
    string value;
    PersonName* prior;

query:
    bool isCurrent {
        not exists PersonName next : next.prior = this
    }
}

Disputable properties

The Entity Property pattern detects conflicts and allows the application to resolve them. To aide the application in this task, Correspondence defines Disputable<T>. This template can be converted to and from the raw type T, but it also exposes two additional properties.

  • InConflict – A boolean that is true if a conflict has been detected.
  • Candidates – A collection of possible values.

Using Disputable<T>, the view model can apply an alternate style when a conflict has been detected, and allow the user to choose from among the candidates to resolve it.

public class PersonViewModel
{
    private Person _person;

    public PersonViewModel(Person person)
    {
        _person = person;
    }

    public string Name
    {
        get { return _person.Name; }
        set { _person.Name = value; }
    }

    public bool ShowConflictStyle
    {
        get { return _person.Name.InConflict; }
    }

    public IEnumerable<string> CandidateNamesItemsSource
    {
        get { return _person.Name.Candidates; }
    }

    public string CandidateNamesSelectedItem
    {
        get { return _person.Name; }
        set { _person.Name = value; }
    }
}

The Factual modeling language specification has been updated to reflect the new mutable keyword. If you’ve created Correspondence models in the past, you will be required to add key and query section headers once you upgrade. Then you will be able to take advantage of mutability.

Leave a Reply

You must be logged in to post a comment.