feat(laeufe): Live-Aktualisierung per Ereignisstrom statt Polling (#53)
Die Abarbeitungsansicht fragte alle zehn Sekunden nach dem Zustand. Jetzt melden vier Datenbank-Trigger `NOTIFY lauf_geaendert, '<laufId>'`, eine LISTEN-Verbindung je Prozess hoert zu, und der Route Handler schiebt weiter. Gemessen: der Haken des Kollegen ist nach 485 ms beim Zuschauer (am Handy 487 ms), vorher bis zu zehn Sekunden. Zwanzig offene Laschen kosten nichts mehr statt zwanzig Abfragen je zehn Sekunden. Das Ereignis kommt aus der Datenbank und nicht aus dem Dienst, aus demselben Grund, aus dem auch die Regeln dort stehen: ein Trigger sieht auch den Seed, eine Migration und die Reparatur per psql. Und NOTIFY erreicht jede Instanz der Anwendung, ohne einen zweiten Dienst. Welche Tabellen melden, haengt an dem, was `laufZustand` liefert — nicht daran, was das Issue vorgeschlagen hat. Mit Triggern nur auf Schrittergebnis und Lauf waere der Strom ein **Rueckschritt** gewesen: das Polling verglich den ganzen Stand und sah deshalb auch Kommentare, ein Strom sieht nur, was gemeldet wird. Der Kommentar des Kollegen waere nie angekommen, und die Seite haette ausgesehen wie immer. Es melden jetzt vier Tabellen, und `laufZustand` traegt `anzahlAnhaenge` — ein Ereignis ohne Entsprechung im Zustand loest nichts aus. Das Polling bleibt als Rueckfall an **derselben** Adresse, unterschieden nur am Accept-Kopf: eine Rechtepruefung, ein Lesemodell, eine Nutzlast. Ein zweiter Endpunkt waere eine zweite Stelle, an der jemand rechtErforderlich vergessen kann. Bei erreichter Obergrenze antwortet der Handler gewoehnlich mit JSON; EventSource meldet darauf einen Fehler und versucht es nicht wieder, also faellt der Client von sich aus zurueck — ohne Sonderfall. Nebenbei zwei Fehler in docs/betrieb/reverse-proxy.md behoben, beide aus #52: `client_max_body_size 8m` bei `ANHANG_MAX_MB=10` haette ein 10-MB-Foto mit 413 abgewiesen, bevor die eigene Meldung zum Zuge kommt. Closes #53 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
3cbd5026f8
commit
4aa79c93ff
@@ -58,6 +58,14 @@ laufzettel.firma.de {
|
||||
# gerade beim Neustart. Der Pfad braucht keine Anmeldung.
|
||||
health_uri /api/gesundheit
|
||||
health_interval 30s
|
||||
|
||||
# Die Live-Aktualisierung ist ein Ereignisstrom (#033). Caddy erkennt das
|
||||
# heute an `Content-Type: text/event-stream` und reicht von sich aus
|
||||
# sofort durch – ausdruecklich gesetzt bleibt es auch dann richtig, wenn
|
||||
# eine Fassung das einmal anders handhabt. Ohne sofortiges Durchreichen
|
||||
# sammelt der Proxy den Strom, und die Seite sieht aus, als sei sie
|
||||
# haengen geblieben.
|
||||
flush_interval -1
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -102,9 +110,16 @@ server {
|
||||
ssl_certificate /etc/letsencrypt/live/laufzettel.firma.de/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/laufzettel.firma.de/privkey.pem;
|
||||
|
||||
# Der CSV-Import schickt die Datei als Text durch eine Server Action. nginx
|
||||
# laesst von sich aus nur 1 MB durch und waere damit die erste Wand.
|
||||
client_max_body_size 8m;
|
||||
# Der CSV-Import schickt die Datei als Text durch eine Server Action, und
|
||||
# seit #032 haengt jemand Fotos an Schritte. nginx laesst von sich aus nur
|
||||
# 1 MB durch und waere damit die erste Wand.
|
||||
#
|
||||
# **Muss ueber `ANHANG_MAX_MB` liegen.** Steht dort die Vorgabe 10, dann
|
||||
# reichen 8m nicht: ein 10-MB-Foto scheitert an nginx mit „413 Request
|
||||
# Entity Too Large“, und die Meldung der Anwendung („Erlaubt sind hoechstens
|
||||
# 10,0 MB“) kommt nie zum Zuge. Wer die Grenze in der Anwendung anhebt,
|
||||
# hebt sie hier mit an — mit etwas Luft fuer den Rahmen des Formulars.
|
||||
client_max_body_size 12m;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
@@ -117,12 +132,22 @@ server {
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
|
||||
# Der Lauf fragt seinen Zustand alle zehn Sekunden nach; 90 s sind
|
||||
# reichlich und fangen einen langsamen Verzeichnis-Abgleich mit ab.
|
||||
# Die Abarbeitungsansicht haelt seit #033 einen **offenen** Strom auf
|
||||
# /api/laeufe/<id>/zustand. Der Server schickt alle 25 s einen
|
||||
# Herzschlag, damit nginx die stille Verbindung nicht schliesst; 90 s
|
||||
# sind reichlich dafuer und fangen einen langsamen Verzeichnis-Abgleich
|
||||
# mit ab. **Unter 30 s darf dieser Wert nicht fallen**, sonst reisst der
|
||||
# Strom zwischen zwei Herzschlaegen immer wieder ab.
|
||||
proxy_read_timeout 90s;
|
||||
|
||||
# Next liefert Seiten stroemend aus. Ohne das haelt nginx die Antwort
|
||||
# zusammen, und die Seite erscheint spuerbar spaeter auf einmal.
|
||||
# Next liefert Seiten stroemend aus, und die Live-Aktualisierung ist ein
|
||||
# Ereignisstrom. Ohne das haelt nginx die Antwort zusammen: die Seite
|
||||
# erscheint spuerbar spaeter auf einmal, und vom Strom kommt gar nichts
|
||||
# an — sie sieht dann aus, als sei sie haengen geblieben.
|
||||
#
|
||||
# Die Anwendung schickt zusaetzlich `X-Accel-Buffering: no` auf der
|
||||
# Antwort des Stroms. Das wirkt auch, wenn hier `on` stuende, und deckt
|
||||
# genau diesen einen Pfad ab; die Zeile hier gilt fuer alles andere.
|
||||
proxy_buffering off;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user