From 1b8b2b9da90be960579cdb3510f166a550a26540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexis=20M=C3=A9taireau?= Date: Wed, 22 Nov 2023 14:22:23 +0100 Subject: [PATCH] Update documentation --- ...ime-collaboration-to-umap-second-week.html | 6 +- feeds/.atom.xml | 6 +- feeds/all-en.atom.xml | 6 +- feeds/all.atom.xml | 6 +- feeds/code.atom.xml | 6 +- pages/umap.html | 121 ++++++++++++++++++ 6 files changed, 136 insertions(+), 15 deletions(-) create mode 100644 pages/umap.html diff --git a/adding-real-time-collaboration-to-umap-second-week.html b/adding-real-time-collaboration-to-umap-second-week.html index 1f3793b..07928b8 100644 --- a/adding-real-time-collaboration-to-umap-second-week.html +++ b/adding-real-time-collaboration-to-umap-second-week.html @@ -55,11 +55,11 @@

One could compare this logic to what happens when you do a git rebase. Here is some pseudo-code:

def merge_features(reference: list, latest: list, incoming: list):
-    """Finds the changes between reference and entrant, and reapplies them on top of latest."""
-    if latest == entrant:
+    """Finds the changes between reference and incoming, and reapplies them on top of latest."""
+    if latest == incoming:
         return latest
 
-    reference_deleted, incoming_added = get_difference(reference, incoming)
+    reference_removed, incoming_added = get_difference(reference, incoming)
 
     # Ensure that items changed in the reference weren't also changed in the latest.
     for removed in reference_removed:
diff --git a/feeds/.atom.xml b/feeds/.atom.xml
index 71174e9..960a322 100644
--- a/feeds/.atom.xml
+++ b/feeds/.atom.xml
@@ -21,11 +21,11 @@
 </ol>
 <p>One could compare this logic to what happens when you do a <code>git rebase</code>. Here is some&nbsp;pseudo-code:</p>
 <div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">merge_features</span><span class="p">(</span><span class="n">reference</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span> <span class="n">latest</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span> <span class="n">incoming</span><span class="p">:</span> <span class="nb">list</span><span class="p">):</span>
-<span class="w">    </span><span class="sd">&quot;&quot;&quot;Finds the changes between reference and entrant, and reapplies them on top of latest.&quot;&quot;&quot;</span>
-    <span class="k">if</span> <span class="n">latest</span> <span class="o">==</span> <span class="n">entrant</span><span class="p">:</span>
+<span class="w">    </span><span class="sd">&quot;&quot;&quot;Finds the changes between reference and incoming, and reapplies them on top of latest.&quot;&quot;&quot;</span>
+    <span class="k">if</span> <span class="n">latest</span> <span class="o">==</span> <span class="n">incoming</span><span class="p">:</span>
         <span class="k">return</span> <span class="n">latest</span>
 
-    <span class="n">reference_deleted</span><span class="p">,</span> <span class="n">incoming_added</span> <span class="o">=</span> <span class="n">get_difference</span><span class="p">(</span><span class="n">reference</span><span class="p">,</span> <span class="n">incoming</span><span class="p">)</span>
+    <span class="n">reference_removed</span><span class="p">,</span> <span class="n">incoming_added</span> <span class="o">=</span> <span class="n">get_difference</span><span class="p">(</span><span class="n">reference</span><span class="p">,</span> <span class="n">incoming</span><span class="p">)</span>
 
     <span class="c1"># Ensure that items changed in the reference weren&#39;t also changed in the latest.</span>
     <span class="k">for</span> <span class="n">removed</span> <span class="ow">in</span> <span class="n">reference_removed</span><span class="p">:</span>
diff --git a/feeds/all-en.atom.xml b/feeds/all-en.atom.xml
index 233431d..1e0c662 100644
--- a/feeds/all-en.atom.xml
+++ b/feeds/all-en.atom.xml
@@ -21,11 +21,11 @@
 </ol>
 <p>One could compare this logic to what happens when you do a <code>git rebase</code>. Here is some&nbsp;pseudo-code:</p>
 <div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">merge_features</span><span class="p">(</span><span class="n">reference</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span> <span class="n">latest</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span> <span class="n">incoming</span><span class="p">:</span> <span class="nb">list</span><span class="p">):</span>
-<span class="w">    </span><span class="sd">&quot;&quot;&quot;Finds the changes between reference and entrant, and reapplies them on top of latest.&quot;&quot;&quot;</span>
-    <span class="k">if</span> <span class="n">latest</span> <span class="o">==</span> <span class="n">entrant</span><span class="p">:</span>
+<span class="w">    </span><span class="sd">&quot;&quot;&quot;Finds the changes between reference and incoming, and reapplies them on top of latest.&quot;&quot;&quot;</span>
+    <span class="k">if</span> <span class="n">latest</span> <span class="o">==</span> <span class="n">incoming</span><span class="p">:</span>
         <span class="k">return</span> <span class="n">latest</span>
 
-    <span class="n">reference_deleted</span><span class="p">,</span> <span class="n">incoming_added</span> <span class="o">=</span> <span class="n">get_difference</span><span class="p">(</span><span class="n">reference</span><span class="p">,</span> <span class="n">incoming</span><span class="p">)</span>
+    <span class="n">reference_removed</span><span class="p">,</span> <span class="n">incoming_added</span> <span class="o">=</span> <span class="n">get_difference</span><span class="p">(</span><span class="n">reference</span><span class="p">,</span> <span class="n">incoming</span><span class="p">)</span>
 
     <span class="c1"># Ensure that items changed in the reference weren&#39;t also changed in the latest.</span>
     <span class="k">for</span> <span class="n">removed</span> <span class="ow">in</span> <span class="n">reference_removed</span><span class="p">:</span>
diff --git a/feeds/all.atom.xml b/feeds/all.atom.xml
index 18e0cb3..1e91c57 100644
--- a/feeds/all.atom.xml
+++ b/feeds/all.atom.xml
@@ -21,11 +21,11 @@
 </ol>
 <p>One could compare this logic to what happens when you do a <code>git rebase</code>. Here is some&nbsp;pseudo-code:</p>
 <div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">merge_features</span><span class="p">(</span><span class="n">reference</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span> <span class="n">latest</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span> <span class="n">incoming</span><span class="p">:</span> <span class="nb">list</span><span class="p">):</span>
-<span class="w">    </span><span class="sd">&quot;&quot;&quot;Finds the changes between reference and entrant, and reapplies them on top of latest.&quot;&quot;&quot;</span>
-    <span class="k">if</span> <span class="n">latest</span> <span class="o">==</span> <span class="n">entrant</span><span class="p">:</span>
+<span class="w">    </span><span class="sd">&quot;&quot;&quot;Finds the changes between reference and incoming, and reapplies them on top of latest.&quot;&quot;&quot;</span>
+    <span class="k">if</span> <span class="n">latest</span> <span class="o">==</span> <span class="n">incoming</span><span class="p">:</span>
         <span class="k">return</span> <span class="n">latest</span>
 
-    <span class="n">reference_deleted</span><span class="p">,</span> <span class="n">incoming_added</span> <span class="o">=</span> <span class="n">get_difference</span><span class="p">(</span><span class="n">reference</span><span class="p">,</span> <span class="n">incoming</span><span class="p">)</span>
+    <span class="n">reference_removed</span><span class="p">,</span> <span class="n">incoming_added</span> <span class="o">=</span> <span class="n">get_difference</span><span class="p">(</span><span class="n">reference</span><span class="p">,</span> <span class="n">incoming</span><span class="p">)</span>
 
     <span class="c1"># Ensure that items changed in the reference weren&#39;t also changed in the latest.</span>
     <span class="k">for</span> <span class="n">removed</span> <span class="ow">in</span> <span class="n">reference_removed</span><span class="p">:</span>
diff --git a/feeds/code.atom.xml b/feeds/code.atom.xml
index 4a2dc59..abd2c71 100644
--- a/feeds/code.atom.xml
+++ b/feeds/code.atom.xml
@@ -21,11 +21,11 @@
 </ol>
 <p>One could compare this logic to what happens when you do a <code>git rebase</code>. Here is some&nbsp;pseudo-code:</p>
 <div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">merge_features</span><span class="p">(</span><span class="n">reference</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span> <span class="n">latest</span><span class="p">:</span> <span class="nb">list</span><span class="p">,</span> <span class="n">incoming</span><span class="p">:</span> <span class="nb">list</span><span class="p">):</span>
-<span class="w">    </span><span class="sd">&quot;&quot;&quot;Finds the changes between reference and entrant, and reapplies them on top of latest.&quot;&quot;&quot;</span>
-    <span class="k">if</span> <span class="n">latest</span> <span class="o">==</span> <span class="n">entrant</span><span class="p">:</span>
+<span class="w">    </span><span class="sd">&quot;&quot;&quot;Finds the changes between reference and incoming, and reapplies them on top of latest.&quot;&quot;&quot;</span>
+    <span class="k">if</span> <span class="n">latest</span> <span class="o">==</span> <span class="n">incoming</span><span class="p">:</span>
         <span class="k">return</span> <span class="n">latest</span>
 
-    <span class="n">reference_deleted</span><span class="p">,</span> <span class="n">incoming_added</span> <span class="o">=</span> <span class="n">get_difference</span><span class="p">(</span><span class="n">reference</span><span class="p">,</span> <span class="n">incoming</span><span class="p">)</span>
+    <span class="n">reference_removed</span><span class="p">,</span> <span class="n">incoming_added</span> <span class="o">=</span> <span class="n">get_difference</span><span class="p">(</span><span class="n">reference</span><span class="p">,</span> <span class="n">incoming</span><span class="p">)</span>
 
     <span class="c1"># Ensure that items changed in the reference weren&#39;t also changed in the latest.</span>
     <span class="k">for</span> <span class="n">removed</span> <span class="ow">in</span> <span class="n">reference_removed</span><span class="p">:</span>
diff --git a/pages/umap.html b/pages/umap.html
new file mode 100644
index 0000000..93f73e2
--- /dev/null
+++ b/pages/umap.html
@@ -0,0 +1,121 @@
+
+
+
+
+    uMap - Alexis Métaireau
+    
+    
+    
+    
+
+
+
+    
+ +
+
+
+

Mardi 23/11/2023 ()

+

J’ai exploré l’utilisation de Websockets pour le transport, entre autre sa consommation mémoire, il semblerait que ce soit tout à fait acceptable (1gb de mémoire permet de gérer 1500 connexions concurrentes).

+

WebRTC n’est actuellement pas supporté par Tor Browser (pour le moment), donc j’imagine que c’est une fausse piste.

+

Lundi 22/11/2023 (8h)

+

Une matinée passée à la fois à préparer la semaine et à rédiger un résumé de ce que j’ai fait la semaine dernière. +J’ai passé un peu plus de temps à comprendre en profondeur le code de merge de la PR de Biondi biondo, pour pouvoir l’expliquer dans un article de blog.

+

L’après-midi j’ai participé à la weekly et lu l’article de blog de Figma qui explique leur approche pour implementer du temps réel.

+

J’avance petit à petite sur la piste d’utiliser un CRDT “maison”, voire pas de CRDT du tout, en fonction de nos besoins réels. Un CRDT nous permettrait d’avoir plusieurs personnes qui travaillent en même temps sur une même feature (au sens GeoJSON), mais je ne sais pas encore si c’est un cas d’usage réel.

+

Vendredi 17/11/2023 (6h)

+

J’ai passé du temps pour essayer de comprendre comment utiliser SQLite en local à l’intérieur d’un navigateur, en utilisant cr-sqlite. J’ai un prototype qui fonctionne à peu près et qui permet de récupérer les éditions en local pour les synchroniser avec une autre base SQLite.

+

Fait un point avec l’équipe sur l’avancement général l’après-midi.

+

Ensuite continué à creuser sur l’utilisation de SQLite avec cr-sqlite.

+

Il faut donc: +- Des clients qui savent quelle est leur version de la base de données qu’ils ont. +- Lorsqu’ils envoie des modifications, on peut demander les modifs depuis la version qui était envoyée précédement. +- Les bases de données peuvent-êtres mergées sans perte de données. Les opérations étant faites en SQL, un CRDT est en fait créé. +- On peut récupérer un fichier SQLite en sortie et l’envoyer au serveur / le stocker en local.

+
    +
  • Exemple d’un syncer dans vlcn - https://github.com/vlcn-io/example-rest/blob/main/src/Syncer.ts
  • +
  • https://observablehq.com/@tantaman/cr-sqlite-basic-setup
  • +
+

Mardi 14/11/2023 (8h)

+

Une matinée passée avec Yohan pour à la fois avancer sur la PR pour merger des conflits simples. On a passé le code en revue et fait quelques changements cosmétiques qui devraient aider à la compréhension générale.

+

La deuxième partie de la matinée à été utilisée pour discuter des découvertes et des questions que je me pose quand à comment faire pour ajouter ces fonctions de collaboration temps réel.

+

Plusieurs trucs à noter : +- Il est possible de challenger l’utilisation de geoJSON pour le stockage des données. On a parlé entre autres de pmtiles et de sqlite.

+

J’ai passé un début d’après-midi à installer mon environnement de travail sur Linux, puis j’ai : +- terminé de rebaser la pull request pour faire un merge optimiste. +- amélioré la vitesse d’execution des tests

+

Découvertes : +- https://www.geopackage.org/ +- https://vlcn.io/docs/js/reactivity

+

Lundi 13/11/2023 (8h)

+

Leaflet et synchronisation

+

J’ai cherché à comprendre comment il serait possible de s’intégrer avec Leaflet. Je connais assez mal l’écosystème donc j’ai cherché les plugins autour de stockage de données et de la synchronisation.

+

Beaucoup de clicks, de lecture et de compréhension des contours de l’écosystème SIG, et de l’écosystème de Leaflet.

+

Deux bibliothèques me paraissent intéressantes dans notre cas:

+
    +
  • Leaflet-GeoSSEpermet d’utiliser SSE (Server Sent Events) pour mettre à jour les données en local. Ça utilise des évènements (create, update, delete) et des clés dans les features GeoJSON.
  • +
  • Leaflet Realtime fait un travail un peu similaire, mais ne parle pas du transport. C’est pensé pour faire du suivi sur un élément externe (tracker GPS par exemple)
  • +
+

Je note que : +- Dans les deux bibliothèques, des identifiants uniques sont donnés aux features pour pouvoir gérer leurs mises à jour. +- Aucune des deux bibliothèque ne gère les ajouts de données et les modifications en local. C’est une partie qui me reste à trouver.

+

Server-Sent Events (SSE)

+

Tout ça m’a fait penser aux SSE, et au fait que je n’ai jamais implémenté ça dans une application en python.

+

J’ai donc continué ma lecture sur ces sujets. J’ai appris que :

+
    +
  • Les SSE font que la connexion au serveur ne s’arrête jamais, (et donc potentiellement consomme un process ?)
  • +
  • Il y a une bibliothèque en Django pour gérer ça, nommée dajngo-eventstream
  • +
  • Django channels est un projet qui vise à utiliser de l’ASGI pour certaines parties.
  • +
  • La bonne nouvelle, c’est qu’il n’est pas forcement nécessaire de tout gérer avec Django. Il est possible de déléguer ça à pushpin, un proxy, en utilisant django-grip
  • +
+

Ça me questionne sur la complexité de l’opération en terme de déploiement.

+

Vu qu’il s’agit à priori plus de clients qui travaillent ensemble, peut-être qu’un possibilité serait de les faire communiquer ensemble directement (en utilisant WebRTC par exemple).

+

État de WebRTC en 2023

+

Django pourrait jouer le role du serveur STUN (pour que le client connaisse son IP publique) et/ou TURN (pour faire le relai des messages si les clients n’arrivent pas à communiquer ensemble). Dans le cas du serveur TURN, on se retrouve avec la même problématique de déploiement plus complexe.

+

Pros : +- Aucune charge sur le serveur

+

Cons : +- Chaque client est connecté à tous les autres, et donc ça peut ne pas fonctionner si beaucoup d’éditions simultanées ont lieu.

+

- https://github.com/yjs/y-webrtc

+

Quelques autres liens que j’ai trouvé utiles : +- Leaflet.offline permet de stocker des données de tuile hors-ligne +- geojson-vtintroduit le concept de “vector tiles” que je ne connaissais pas. Les tuiles peuvent donc retourner des données binaires (raster) ou bien des données vectorielles. + Ce projet permet de stocker du geojson dans des tuiles vectorielles. +- mapbox-gl-js permet de faire un rendu de données cartographiques en utilisant WebGL (aucun lien avec Leaflet) +- leaflet-ugeojson et leaflet.Sync permettent d’avoir des cartes dont la vue est synchronisée

+

Mardi 07/11/2023 (8h)

+
    +
  • Lu la documentation d’automerge
  • +
  • Commencé à faire un prototype pour voir le fonctionnement d’automerge en python
  • +
  • Installé les dépendances rust, compilé automerge
  • +
  • Réunion discussion avec Yohan sur mes questions et sur les différentes pistes
  • +
+

Lundi 06/11/2023 (4h)

+
    +
  • Lu le code qui est dans uMap actuellement pour comprendre le fonctionnement actuel
  • +
  • Commencé à rédiger un document avec les différentes options pour faire de la synchro
  • +
  • Fais des recherches sur les différentes options pour faire de la synchro
  • +
+
+ +
+ + + \ No newline at end of file