Workers P2: Zeitgrenze je Abruf und Sperre für frische JWTs nach einer 401-Folge
Endprüfung P2. Ein Abruf auf toter Verbindung (Rechner im Ruhezustand, Netzwechsel) blieb offen, und die Feed-Schleifen laufen mit einem Abruf je Schleife: die Seite stand still und zeigte veraltete Daten als aktuell. createWorkersApi bricht jetzt jeden Versuch (JWT holen, senden, Antwort lesen) nach 20 s mit "Der Hustler-Dienst ist gerade nicht erreichbar." (status 0) ab, auch wenn fetch oder createJWT das Signal nicht beachten. Außerdem erzwang jede 401-Antwort ein frisches createJWT, bei dauerhaftem 401 etwa 16 bis 20 Mal je Minute und Tab. Appwrite begrenzt createJWT je Nutzer; das Limit hätte auch Serverpuls, Finanzen und Vorschauen gesperrt. Nach einer 401-Folge (frisches JWT wird ebenfalls abgelehnt oder lässt sich nicht erzeugen) gibt es 2 Minuten lang kein frisches JWT mehr, die Meldung "Anmeldung abgelaufen" bleibt; Erfolg hebt die Sperre auf. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
820ccd510d
commit
9ebc562c83
3 files changed
+234
-11
No files matched your search
@@ -6,6 +6,7 @@ import { loadModule } from './load.mjs'
|
||||
// Feed-Steuerung der Hustler-Seite: Zustand 15 s, Ereignisse 5 s, Cursor, Seiten, Sichtbarkeit, Fehler.
|
||||
// Alles mit Fake-Timern und einer Fake-API (kein Netz, keine echte Zeit).
|
||||
const { createFeedController } = await loadModule('src/lib/workersFeed.js')
|
||||
const { createWorkersApi } = await loadModule('src/lib/workersApi.js')
|
||||
|
||||
const nextTick = () => new Promise((resolve) => setImmediate(resolve))
|
||||
|
||||
@@ -396,3 +397,39 @@ test('200 Ereignisse mit demselben ts halten den Feed nicht an (Fremd-API ohne e
|
||||
assert.equal(new Set(all).size, all.length)
|
||||
assert.deepEqual(h.log.errors, [])
|
||||
})
|
||||
|
||||
test('hängender Abruf (tote Verbindung): die Zeitgrenze des API-Clients gibt die Schleife frei, Fehler erscheint und verschwindet wieder (Endprüfung P2)', async () => {
|
||||
// Echter createWorkersApi mit kurzer Zeitgrenze, echte Timer mit kurzen Takten: der erste Zustands-Abruf kommt nie an
|
||||
const state = { lastEventTs: '2026-10-17T20:00:00.000Z', workers: [] }
|
||||
const urls = []
|
||||
let hungOnce = false
|
||||
const fetchImpl = async (url) => {
|
||||
urls.push(url)
|
||||
if (url.endsWith('/state') && !hungOnce) {
|
||||
hungOnce = true
|
||||
return new Promise(() => {})
|
||||
}
|
||||
return { ok: true, status: 200, json: async () => (url.endsWith('/state') ? state : { events: [] }) }
|
||||
}
|
||||
const api = createWorkersApi({ getJwt: async () => 'jwt', fetchImpl, timeoutMs: 40 })
|
||||
const snapshots = []
|
||||
const errors = []
|
||||
const c = createFeedController({
|
||||
api,
|
||||
setTimer: (fn, ms) => setTimeout(fn, ms),
|
||||
clearTimer: (id) => clearTimeout(id),
|
||||
isVisible: () => true,
|
||||
onSnapshot: (x) => snapshots.push(x),
|
||||
onError: (e) => errors.push(e ? e.message : null),
|
||||
stateMs: 20,
|
||||
eventsMs: 20,
|
||||
})
|
||||
c.start()
|
||||
const until = async (ok) => {
|
||||
for (let i = 0; i < 100 && !ok(); i += 1) await new Promise((r) => setTimeout(r, 20))
|
||||
}
|
||||
await until(() => snapshots.length > 0)
|
||||
c.stop()
|
||||
assert.ok(snapshots.length >= 1, 'nach der Zeitgrenze kommt der Zustand doch noch')
|
||||
assert.deepEqual(errors, ['Der Hustler-Dienst ist gerade nicht erreichbar.', null])
|
||||
})
|
||||
Reference in new issue
Block a user