Nous venons de définir la cohérence séquentielle et de proposer une approche pour la réaliser. Néanmoins nous avons vu que cette approche est limitée puisqu’elle pousse le système à être nivelé par le bas en s’adaptant à l’acteur le plus lent.
Nous allons donc explorer d’autres approches réalisant plus de compromis dans la gestion de la cohérence du système.

Ainsi là où la cohérence séquentielle (et par extension la cohérence forte) permettait de garantir nos 3 propriété que sont la validité, la convergence et la localité d’état. Nous allons explorer des solutions qui certaines de ces propriétés afin de gagner en performance et en résilience.

\subsection{Adaptation à notre problème}

Dans le cadre de notre problématique il convient dans un premier temps de spécifier quels sont les critères qui semblent être essentiels à la réalisation d’une application d’édition collaborative. Pour ça nous pouvons déjà imaginer ce qu’impliquent concrètement ces différents critères sur le comportement de notre application.

\subsubsection{Validité}

Comme dit précédemment, la validité permet d’assurer que les saisies de Bob soient toujours prises en compte en tout point du système. C’est-à-dire que si Bob saisit “Hello” puis “World” alors il s’attend à ce que ces deux saisies soient prises en compte. Ce qui se traduit par l’affichage de « Hello World » ou « World Hello sur son écran. Les états finaux incorrects qui ne respecterait pas la validité sont alors “Hello”, “World” ou "$\emptyset$".

De la même manière, les saisies des aitres acteurs du système peuvent donc très bien être ignorés, intercalés entre les saisis de Bob, et réagencés durant l’exécution.

Ne pas prendre en compte le critère de validité dans notre application reviendrait donc à être capable d’ignorer des saisies soumises par l’utilisateur. C’est ce qui est formalisé par le critère de cohérence dit de Sérialisation (selon Perrin).

L’application de la validité demande à notre système une approche d’acknowledgement. Puisque toutes saisies ce doit d’être considéré, le client doit s’assurer que sa saisie a bien été reçue par l’ensemble des nœuds. Dans le cas d’une application centralisé, seul un intermédiaire doit être contacté. Mais dans un contexte plus distribué, le problème augmente en complexité et en coût pour le réseau.

\paragraph{La Sérialisation}

La sérialisation se propose donc comme étant l’exact inverse de la validité, c’est-à-dire un critère de cohérence fort auquel nous aurions retiré la validité. ($SER = \{C_\top\} - \{V\}$)

\subsubsection{Convergence}

La convergence permet d’assurer que le document final soit identique pour tous les acteurs. C’est-à-dire que, peu importe l’ordre dans lequel les saisies ont été reçus par chaque nœud, le document final doit être identique pour tous.

Il est important de noter que la convergence seule ne dit rien sur la source des données qui composent le document. Ainsi il est possible que le document final ne prenne pas en compte toutes les saisies réalisées sur le système. Ou bien même qu’il prenne en compte des saisies qui n’ont jamais été réalisées.

Appliqué à notre problème, la convergence assure que le document final soit identique pour tous les acteurs, ce qui peut sembler essentiel dans notre cas.

L’application de la convergence introduit dans notre système une notion de gestion des conflits. Si plusieurs acteurs souhaitent écrire au même moments, alors des mécanismes doivent être mis en place pour une gestion des conflits déterministe. C’est-à-dire, permettant de garantir une seule version pour tous les acteurs quelle que soit sa position dans le système, et donc l’ordre potentiel de réception des saisies.

[Un exemple de gestion de conflits pas si évidente que ça]

Cette gestion des conflits peut être réalisée de manière distribuée impliquant la mise en place d’un algorithme de consensus. Ce qui peut être très couteux en termes de performance et de complexité. Ou bien être délégué à un acteur centralisé qui aura le pouvoir de manipuler l’ordre final des saisies. Ce qui peut poser des problèmes en termes de gouvernance du système, donnant le pouvoir à un seul acteur.

Il est bon de noter que bien que la convergence est une propriété qui semble importante dans le cadre d’une application d’édition collaborative classique. Il existe des manières de concevoir une application collaborative fournissant un document final identique, mais ne garantissant pas nécessairement la convergence dans l’ordre où les saisies sont interprétées. Ce point sera discuté lorsque nous aborderons les CRDTs.

\subsubsection{Localité d’état}

La localité d’état permet d’assurer que les mises à jour d’affichages futurs soient toujours cohérentes avec les mises à jour d’affichages passés. Indirectement, cela interdit le changement de l’ordre dans lequel les transactions passées sont interprétés une fois que le résultat est affiché à l’utilisateur. Mais empêche aussi l’insertion et la suppression de transactions dans ce même passé.

L’objectif à haut niveau est de garder une expérience cohérente pour l’utilisateur, en interdisant à l’application de tolérer des retours en arrières de l’état courant.

Appliqué à notre problème, la localité d’état permet d’assurer que les saisies de Bob et celles qu’il a reçu soient toujours affichés dans l’ordre où elles ont été interprétées initialement. Cette propriété permet par exemple d’empêcher le cas où Alice traiterait la saisie de bob, bob de son côté supprime la saisie qu’il vient de réaliser, et Alice renvoi à Bob la saisie qu’elle vient de modifier. Ce cas est explicité dans la figure \ref{local_state_fail}.



\begin{figure}[! h]
    \centering
    \resizebox{!}{0.7\columnwidth}{
        \input{images/localiteEtatFail.latex}
    }
    \caption{Localité d’état non respectée}
    \label{local_state_fail}
\end{figure}

Du point de vue de Bob, il vient de revoir apparaitre une ligne qu’il vient de supprimer, ce qui rend son expérience incohérente.

En effet, premièrement Bob à vue s’afficher sur son écran la ligne qu’il venait de saisir \\ $\delta = \{"Hello World"\}$ qui est le résultat de l’exécution $\text{insérer}("Hello World")$. Puis il supprime le mot “World”. Le passé des exécutions de Bob devient donc $\text{insérer}("Hello World") \cdot \text{supprimer}("World") = \{"Hello"\}$. Mettant ainsi à jour son état local. Enfin il recoit l’opération d’Alice qui vient de réaliser une modification en se basant sur un état antérieur à l’état actuel de Bob. L’état qu’il reçoit est donc le résultat des opérations $\text{insérer}("Hello World") \cdot \text{insérer}("Hello World") = \{"Hello World"\}$. On omet ici une opération que Bob à soumise, qu’il a pu constater comme étant comptabilisé dans le calcul de son état local, mais qui a ensuite été ignoré par le système. La cohérence de l’état local de Bob n’a donc pas était respectée.


% \subsection{État des différents critères}
% \subsubsection{Les modèles de mémoires partagées}

% \subsubsection{La cohérence forte}
% Cohérence Séquentielle \cite{lamport_how_1979}

% \subsubsection{La cohérence Faible}
