Passa al contenuto principale

Come funziona EntityFlow

EntityFlow è costruito attorno a un piccolo insieme di decisioni architetturali che mantengono il suo comportamento deterministico, testabile e identico tra l'applicazione web, il server e la build desktop.

Separazione core/shell​

Tutta la logica deterministica risiede in pacchetti TypeScript headless e indipendenti da qualsiasi framework. L'applicazione React, il server Node e l'applicazione Electron sono shell sottili che li consumano: non contengono alcuna logica di business propria.

I pacchetti headless coprono:

  • l'IR dello schema (rappresentazione intermedia),
  • il modello di documento CRDT,
  • la geometria e l'instradamento degli archi,
  • la generazione di codice SQL/DBML su quattro dialetti,
  • la validazione,
  • la proiezione (modello di lettura),
  • il renderer della tela,
  • l'autorizzazione.

Poiché la logica è condivisa, ciò che vedi nel browser, ciò che il server esporta e ciò che l'applicazione desktop produce provengono tutti dallo stesso codice.

Doppia persistenza (CQRS)​

EntityFlow utilizza una separazione comando/query con due rappresentazioni di ogni diagramma:

  • Il modello di scrittura autoritativo è un Yjs CRDT, memorizzato come blob binario. Ogni modifica muta questo blob.
  • Una proiezione di lettura relazionale viene derivata dal blob per le query, la ricerca e l'esportazione lato server.

Il flusso è rigorosamente unidirezionale:

CRDT blob → IR → projection rows

La proiezione non viene mai riscritta nel blob. Se una riga della proiezione dovesse mai divergere o fallire, viene semplicemente riderivata dal blob: il blob è l'unica fonte di verità.

Tempo reale​

Un server websocket Hocuspocus viene eseguito nello stesso processo Node dell'API e sincronizza il CRDT tra gli editor connessi. La presenza in tempo reale (cursori, selezioni, chi è online) viaggia tramite l'awareness di Yjs, che non viene mai persistita: esiste solo per la durata di una connessione.

note

Poiché l'esportazione lato server viene emessa dall'IR derivata dal blob, il SQL/DBML che produce è identico byte per byte a ciò che esporta l'editor nel browser.

Scalabilità orizzontale​

Un singolo nodo gestisce da solo un carico di lavoro considerevole. Per eseguire più di una replica del server, abilita il fan-out con Redis in modo che l'awareness e gli aggiornamenti dei documenti si propaghino tra i pod. Senza di esso, le repliche divergono. Consulta Scalabilità e prestazioni per i dettagli e gli obiettivi SLO.