SpacetimeDB er nå helt fjernet fra Synops. Sanntid håndteres av PG LISTEN/NOTIFY + WebSocket i portvokteren (maskinrommet). Kode fjernet: - spacetimedb/ Rust-modul og spacetime.json - maskinrommet/src/stdb.rs (HTTP-klient for STDB-reducers) - frontend module_bindings/ (23 auto-genererte filer) - spacetimedb npm-avhengighet fra package.json - scripts/test-sanntid.sh (testet STDB-flyt) Infrastruktur: - Docker-container stoppet og fjernet fra docker-compose.yml - Caddy: fjernet /spacetime/* reverse proxy - maskinrommet-env.sh: fjernet STDB_IP og SPACETIMEDB_*-variabler - .env.example: fjernet SpacetimeDB-seksjoner Dokumentasjon oppdatert: - CLAUDE.md: stack, lagmodell, kjerneprinsipper, driftsmodell - docs/arkitektur.md: skrivestien, lesestien, datalag, teknologivalg - docs/retninger/datalaget.md: migrasjonshistorikk, status "fjernet" - 37 andre docs oppdatert (features, concepts, infra, ops, retninger) - Alle kode-kommentarer med STDB-referanser oppdatert Verifisert: maskinrommet bygger og starter OK, frontend bygger OK, helsesjekk returnerer 200. Caddy reloadet.
111 lines
3.9 KiB
Markdown
111 lines
3.9 KiB
Markdown
# Synkronisering: SpacetimeDB ↔ PostgreSQL
|
|
|
|
> **UTGÅTT (mars 2026).** SpacetimeDB er fjernet fra prosjektet.
|
|
> Sanntid leveres nå via PG LISTEN/NOTIFY + WebSocket i portvokteren.
|
|
> Se `docs/infra/api_grensesnitt.md` for gjeldende arkitektur.
|
|
> Dokumentet beholdes som historisk referanse.
|
|
|
|
## Konsept
|
|
|
|
SpacetimeDB holder hele grafen (alle noder og edges) i minne.
|
|
PostgreSQL er persistent backup og arkiv. Skriving går til begge.
|
|
Lesing går fra SpacetimeDB.
|
|
|
|
```
|
|
GUI (SvelteKit)
|
|
│ skriv │ les (sanntid)
|
|
▼ ▼
|
|
Maskinrommet (Rust) SpacetimeDB ──→ GUI
|
|
│ ▲
|
|
├──→ PostgreSQL (persistent) │
|
|
└──→ SpacetimeDB ───────────┘
|
|
```
|
|
|
|
## Hvorfor hele grafen i SpacetimeDB
|
|
|
|
Node- og edge-skjemaet er minimalt: åtte kolonner på nodes, åtte
|
|
på edges. For en liten brukerbase er hele grafen triviell å holde
|
|
i minne. Dette forenkler alt:
|
|
|
|
- Ingen sync-logikk for å bestemme hva som er "aktivt"
|
|
- Ingen henting fra PG når noen åpner noe gammelt
|
|
- Frontend har alltid alt tilgjengelig via WebSocket
|
|
- Én lesekilde — ingen tvetydighet
|
|
|
|
Når dette *blir* problematisk (hundretusenvis av noder, minnepress),
|
|
innføres eviction basert på aksessmønstre. Men det er en
|
|
optimaliseringsbeslutning, ikke en arkitekturbeslutning. Modellen
|
|
endres ikke.
|
|
|
|
## Skrivestien
|
|
|
|
Maskinrommet validerer, så skriver i to steg:
|
|
|
|
1. **Validering** — tilgangssjekk, unique-constraints, forretningsregler
|
|
2. **SpacetimeDB først** — frontend oppdateres umiddelbart (~10μs)
|
|
3. **PG asynkront** — persistent backup i bakgrunnen
|
|
|
|
Frontend er allerede oppdatert mens PG-skrivingen skjer. Brukeren
|
|
merker ingenting.
|
|
|
|
Hvis PG-skrivingen feiler: maskinrommet logger og prøver igjen.
|
|
SpacetimeDB har dataen — den er bare ikke persistert ennå. Ingen
|
|
datatap så lenge SpacetimeDB kjører.
|
|
|
|
## Lesestien
|
|
|
|
Frontend leser **kun fra SpacetimeDB** via WebSocket-subscriptions.
|
|
Ingen PG-kall fra frontend for data som vises i sanntid.
|
|
|
|
Unntak: tunge spørringer som ikke passer sanntidslaget — statistikk,
|
|
fulltekstsøk, pgvector-søk, AGE-traverseringer. Disse går
|
|
GUI → Maskinrommet → PG.
|
|
|
|
## Oppvarming (PG → SpacetimeDB)
|
|
|
|
Ved oppstart av SpacetimeDB laster maskinrommet hele grafen fra PG:
|
|
|
|
1. Alle noder
|
|
2. Alle edges
|
|
3. `node_access`-matrisen
|
|
|
|
Rekkefølge: noder først (edges refererer til noder).
|
|
CAS-noder lastes uten binærinnhold (bare metadata).
|
|
|
|
## Feilhåndtering
|
|
|
|
| Scenario | Konsekvens | Håndtering |
|
|
|----------|-----------|------------|
|
|
| SpacetimeDB krasjer | Sanntid forsvinner, upersistert data kan tapes | Restart + oppvarming fra PG. Tap begrenset til skrivinger som ikke rakk PG. |
|
|
| PG nede | Persistering stopper | SpacetimeDB serverer lesing og mottar skrivinger. PG-backlog tas igjen ved recovery. |
|
|
| Maskinrommet krasjer | Ingen skriving | Frontend ser siste state. Restart plukker opp. |
|
|
|
|
## SpacetimeDB som utbyttbar
|
|
|
|
SpacetimeDB er en sanntidscache, ikke en avhengighet. Hvis den
|
|
fjernes fra stacken:
|
|
|
|
- **Sanntid:** PG `LISTEN/NOTIFY` → SvelteKit SSE
|
|
- **Skriving:** Maskinrommet → PG direkte
|
|
- **Lesing:** Maskinrommet → PG → GUI
|
|
|
|
Denne fallbacken trenger ikke implementeres, men arkitekturen
|
|
skal aldri gjøre den umulig.
|
|
|
|
## Tilgangsmatrise i SpacetimeDB
|
|
|
|
`node_access`-matrisen lastes inn i SpacetimeDB ved oppvarming.
|
|
Når maskinrommet oppdaterer matrisen i PG (ved edge-endring),
|
|
oppdaterer den også SpacetimeDB. SpacetimeDB-modulen bruker
|
|
matrisen for å filtrere subscriptions — klienter ser kun noder
|
|
de har tilgang til.
|
|
|
|
## Konflikthåndtering
|
|
|
|
SpacetimeDB er single-threaded per modul — reducer-funksjoner
|
|
serialiseres automatisk. Ingen klassiske race conditions.
|
|
|
|
Samtidig redigering (to brukere endrer samme node): maskinrommet
|
|
serialiserer via SpacetimeDB. Last-write-wins. SpacetimeDB
|
|
kringkaster resultatet til alle klienter. PG oppdateres asynkront
|
|
med det endelige resultatet.
|