Eine Stage laesst sich nicht wiederholen. Zwei Dinge durften deshalb nicht so bleiben, wie sie waren. Erstens die Uhr. Zeiten entstehen auf den Geraeten an der Strecke — nur so laesst sich im Funkloch ueberhaupt stoppen. Damit steckte aber der Versatz zweier Telefonuhren in jeder Dauer, bei der einer am Start und ein anderer im Ziel drueckt. Jedes Geraet gleicht sich jetzt gegen den Server ab (Cristian: t0 merken, Serverzeit holen, t1 merken, Versatz = T + RTT/2 - t1), sieben Proben, Median ueber die schnellste Haelfte. Der Versatz liegt im localStorage und wird auf jeden Zeitstempel gerechnet. Dafuer eine eigene Route /api/clock in den Hooks: Der Date-Header jeder gewoehnlichen Antwort hat nach RFC 9110 Sekundenaufloesung, allein daraus folgte ein Fehler von bis zu einer halben Sekunde — auf einer Stage der Unterschied zwischen Platz eins und Platz drei. Zweitens das Netz. Scheitert die Uebertragung eines Starts oder Stopps an einem Funkloch, wandert er in einen Ausgang im localStorage statt in einen Fehler und geht raus, sobald wieder Empfang da ist. Die massgebliche Zeit ist die des Druckens, nicht die der Uebertragung. Ein Stopp kann dabei auf einen Start warten, der selbst noch aussteht. Unterschieden wird streng zwischen Funkloch und Absage: Eine abgelehnte Anfrage — fehlende Rechte, ungueltige Daten — wird gemeldet und nicht aufgefangen, sonst sammelte der Ausgang stumm Eintraege, die auch beim naechsten Versuch scheitern. Die Leiste der laufenden Zeiten zeigt nicht uebertragene Zeiten ganz oben und erscheint dafuer auch dann, wenn gerade nichts laeuft. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P32KoesVtABd6xWsqMKzhr
21 lines
933 B
JavaScript
21 lines
933 B
JavaScript
/// <reference path="../pb_data/types.d.ts" />
|
|
|
|
// Die gemeinsame Uhr.
|
|
//
|
|
// Zeiten entstehen auf den Geraeten an der Strecke, nicht auf dem Server:
|
|
// Nur so laesst sich im Funkloch ueberhaupt stoppen. Damit steckt aber der
|
|
// Versatz zweier Telefonuhren in jeder Messung, bei der einer startet und ein
|
|
// anderer stoppt. Also braucht es eine Referenz, gegen die sich jedes Geraet
|
|
// vor dem Event abgleicht — und das ist diese Route.
|
|
//
|
|
// Warum nicht der `Date`-Header jeder beliebigen Antwort: Der hat nach
|
|
// RFC 9110 Sekundenaufloesung. Allein daraus folgte ein Fehler von bis zu
|
|
// einer halben Sekunde — auf einer Stage der Unterschied zwischen Platz eins
|
|
// und Platz drei. Hier kommen Millisekunden.
|
|
//
|
|
// Ohne Login: Es ist die Uhrzeit. Sie verraet nichts, was nicht jede Antwort
|
|
// des Servers ohnehin im Date-Header mitschickt.
|
|
|
|
routerAdd('GET', '/api/clock', (e) => {
|
|
return e.json(200, { now: Date.now() })
|
|
})
|