Sporadische Zeitueberschreitungen beim Abgleich #23

Closed
opened 2026-09-09 20:30:00 +00:00 by florian.wilde · 2 comments
Owner

Seit #19 sichtbar: beim Abgleich von florian.wilde/flimmer liefen issues und pullRequests in HTTP 408: Zeitueberschreitung nach 15000 ms. Nicht alle acht Teil-Abrufe, nur zwei.

Gemessen

Dieselben Aufrufe von außen gegen dieselbe Instanz:

issues (wie Nebula)   200    90ms   0 Eintraege
issues (nochmal)      200    76ms   0 Eintraege
pulls  (wie Nebula)   200    77ms   0 Eintraege
pulls  (nochmal)      200    72ms   0 Eintraege

80 Millisekunden gegen 15 Sekunden. Der Endpunkt ist es nicht, und es sind auch nicht alle Aufrufe — es ist sporadisch und trifft wechselnde.

Zu tun

Der Befund, auf den es ankommt: derselbe Aufruf klappt, wenn er allein läuft. Das legt einen einzelnen Nachschlag nahe statt einer Umstellung ins Blaue — was in der Achterrunde hängen geblieben ist, wird danach noch einmal einzeln versucht. Bleibt es dabei, ist es kein Zufall, und der Fehler steht wie bisher am Repository.

Zusätzlich zu erwägen: die acht Aufrufe nicht alle gleichzeitig losschicken. Das ist allerdings eine Vermutung über die Ursache, kein Befund — der Nachschlag ist die Maßnahme, die sich aus dem Gemessenen ergibt.

Was dabei nicht passieren darf: dass ein Nachschlag den Abgleich spürbar verlangsamt, wenn die Gegenseite wirklich weg ist. Ein Versuch, nicht drei.

Seit #19 sichtbar: beim Abgleich von `florian.wilde/flimmer` liefen `issues` und `pullRequests` in `HTTP 408: Zeitueberschreitung nach 15000 ms`. Nicht alle acht Teil-Abrufe, nur zwei. ## Gemessen Dieselben Aufrufe von außen gegen dieselbe Instanz: ``` issues (wie Nebula) 200 90ms 0 Eintraege issues (nochmal) 200 76ms 0 Eintraege pulls (wie Nebula) 200 77ms 0 Eintraege pulls (nochmal) 200 72ms 0 Eintraege ``` 80 Millisekunden gegen 15 Sekunden. Der Endpunkt ist es nicht, und es sind auch nicht alle Aufrufe — es ist sporadisch und trifft wechselnde. ## Zu tun Der Befund, auf den es ankommt: **derselbe Aufruf klappt, wenn er allein läuft.** Das legt einen einzelnen Nachschlag nahe statt einer Umstellung ins Blaue — was in der Achterrunde hängen geblieben ist, wird danach noch einmal einzeln versucht. Bleibt es dabei, ist es kein Zufall, und der Fehler steht wie bisher am Repository. Zusätzlich zu erwägen: die acht Aufrufe nicht alle gleichzeitig losschicken. Das ist allerdings eine Vermutung über die Ursache, kein Befund — der Nachschlag ist die Maßnahme, die sich aus dem Gemessenen ergibt. Was dabei nicht passieren darf: dass ein Nachschlag den Abgleich spürbar verlangsamt, wenn die Gegenseite wirklich weg ist. Ein Versuch, nicht drei.
florian.wilde added the in-arbeit label 2026-09-09 20:41:17 +00:00
florian.wilde started working 2026-09-09 20:41:25 +00:00
Author
Owner

🤖 Claude Code hat mit der Umsetzung begonnen.

  • Branch: fix/23-nachschlag-bei-timeout
  • Verstanden als: Was in der Achterrunde hängen bleibt, bekommt einen zweiten Versuch — einzeln, nicht gleichzeitig. Der Befund dahinter ist, dass derselbe Aufruf allein in 80 ms antwortet.
  • Geplantes Vorgehen:
    • Teilabrufe hängt Fehlschläge an eine Kette, sodass die Nachschläge nacheinander laufen und sich nicht erneut gegenseitig im Weg stehen. Die Aufrufstellen in den drei Clients bleiben unverändert — hol liefert weiterhin den endgültigen Wert
    • Nachgeschlagen wird nur, wo es Sinn ergibt: bei 408 (Zeitüberschreitung) und 0 (Verbindung kam nicht zustande). Ein 403 wird durch Wiederholen nicht besser, ein 429 durch sofortiges Wiederholen schlimmer
    • Höchstens zwei Nachschläge je Abgleich. Sonst summieren sich acht Zeitüberschreitungen zu zwei Minuten, und der Knopf „Jetzt synchronisieren" fühlt sich an wie ein Absturz
    • Klappt der zweite Versuch auch nicht, steht das am Repository — mit dem Vermerk, dass nachgeschlagen wurde

Was ich nicht mache: die acht Aufrufe entzerren. Das wäre eine Vermutung über die Ursache; der Nachschlag ist die Maßnahme, die sich aus dem Gemessenen ergibt. Wenn das Problem danach bleibt, sagt uns der Vermerk genau das — und dann ist die Entzerrung dran.

Zeiterfassung läuft.

🤖 **Claude Code hat mit der Umsetzung begonnen.** - Branch: `fix/23-nachschlag-bei-timeout` - Verstanden als: Was in der Achterrunde hängen bleibt, bekommt einen zweiten Versuch — einzeln, nicht gleichzeitig. Der Befund dahinter ist, dass derselbe Aufruf allein in 80 ms antwortet. - Geplantes Vorgehen: - `Teilabrufe` hängt Fehlschläge an eine Kette, sodass die Nachschläge **nacheinander** laufen und sich nicht erneut gegenseitig im Weg stehen. Die Aufrufstellen in den drei Clients bleiben unverändert — `hol` liefert weiterhin den endgültigen Wert - **Nachgeschlagen wird nur, wo es Sinn ergibt:** bei `408` (Zeitüberschreitung) und `0` (Verbindung kam nicht zustande). Ein `403` wird durch Wiederholen nicht besser, ein `429` durch sofortiges Wiederholen schlimmer - **Höchstens zwei** Nachschläge je Abgleich. Sonst summieren sich acht Zeitüberschreitungen zu zwei Minuten, und der Knopf „Jetzt synchronisieren" fühlt sich an wie ein Absturz - Klappt der zweite Versuch auch nicht, steht das am Repository — mit dem Vermerk, dass nachgeschlagen wurde Was ich **nicht** mache: die acht Aufrufe entzerren. Das wäre eine Vermutung über die Ursache; der Nachschlag ist die Maßnahme, die sich aus dem Gemessenen ergibt. Wenn das Problem danach bleibt, sagt uns der Vermerk genau das — und dann ist die Entzerrung dran. Zeiterfassung läuft.
florian.wilde worked for 4 minutes 2026-09-09 20:46:20 +00:00
florian.wilde added zu-testen and removed in-arbeit labels 2026-09-09 20:47:03 +00:00
Author
Owner

✅ Umsetzung abgeschlossen — bereit zum Testen.

Was geändert wurde

  • Teilabrufe schlägt hängengebliebene Aufrufe einmal nach — an einer Kette, also nacheinander statt wieder im Schwung
  • Gelöst in Teilabrufe statt hinter dem Promise.all: die Aufrufstellen in den drei Clients bleiben unberührt, hol() liefert weiterhin den endgültigen Wert
  • Nur bei 408 und 0. Ein 403 wird durch Wiederholen nicht besser, ein 429 schlimmer, ein 404 bleibt ein 404
  • Höchstens zweimal je Abgleich — acht Zeitüberschreitungen zu je 15 s wären zwei Minuten
  • Scheitert auch der zweite Versuch, steht am Repository „(auch im zweiten Versuch)"
  • Am Rande behoben: den beiden afterEach-Blöcken in http.test.ts fehlte restoreAllMocks, die Spies zählten über Tests hinweg weiter. Den Fehler hatte ich mit den Teilabrufe-Tests selbst hineingetragen

Nicht gemacht: die acht Aufrufe entzerren. Das wäre eine Vermutung über die Ursache. Bleibt das Problem, sagt der Vermerk genau das — dann ist die Entzerrung dran.

Geänderte Dateien

  • src/lib/git/http.ts · src/lib/git/http.test.ts · FEATURES.md

So testest du es

  1. git switch fix/23-nachschlag-bei-timeout, npm run dev
  2. Normal synchronisieren — es darf sich nichts ändern, solange nichts hängen bleibt
  3. Zum Erzwingen: GIT_API_TIMEOUT_MS=1000 in die .env und ein Repository mit vielen Commits synchronisieren. Erwartet: einzelne Felder werden nachgeschlagen, und was dann noch fehlt, trägt „(auch im zweiten Versuch)"
  4. Danach GIT_API_TIMEOUT_MS wieder herausnehmen

Geprüft: tsc sauber · 295 Unit-Tests grün (vorher 289) · npm run build durch · gegengeprobt, dass mit abgeschaltetem Nachschlag vier der sechs neuen Tests fallen und die beiden, die das Ausbleiben prüfen, grün bleiben.

Aufgewendete Zeit: 00:05
Pull Request: #25

Nach Freigabe: /issue-freigabe 23

✅ **Umsetzung abgeschlossen — bereit zum Testen.** <!-- claude-status branch: fix/23-nachschlag-bei-timeout pr: 25 zeit_sekunden: 295 --> **Was geändert wurde** - `Teilabrufe` schlägt hängengebliebene Aufrufe **einmal** nach — an einer Kette, also nacheinander statt wieder im Schwung - Gelöst in `Teilabrufe` statt hinter dem `Promise.all`: die Aufrufstellen in den drei Clients bleiben unberührt, `hol()` liefert weiterhin den endgültigen Wert - **Nur bei `408` und `0`.** Ein `403` wird durch Wiederholen nicht besser, ein `429` schlimmer, ein `404` bleibt ein `404` - **Höchstens zweimal je Abgleich** — acht Zeitüberschreitungen zu je 15 s wären zwei Minuten - Scheitert auch der zweite Versuch, steht am Repository „(auch im zweiten Versuch)" - Am Rande behoben: den beiden `afterEach`-Blöcken in `http.test.ts` fehlte `restoreAllMocks`, die Spies zählten über Tests hinweg weiter. Den Fehler hatte ich mit den `Teilabrufe`-Tests selbst hineingetragen **Nicht gemacht:** die acht Aufrufe entzerren. Das wäre eine Vermutung über die Ursache. Bleibt das Problem, sagt der Vermerk genau das — dann ist die Entzerrung dran. **Geänderte Dateien** - `src/lib/git/http.ts` · `src/lib/git/http.test.ts` · `FEATURES.md` **So testest du es** 1. `git switch fix/23-nachschlag-bei-timeout`, `npm run dev` 2. Normal synchronisieren — es darf sich nichts ändern, solange nichts hängen bleibt 3. Zum Erzwingen: `GIT_API_TIMEOUT_MS=1000` in die `.env` und ein Repository mit vielen Commits synchronisieren. Erwartet: einzelne Felder werden nachgeschlagen, und was dann noch fehlt, trägt „(auch im zweiten Versuch)" 4. Danach `GIT_API_TIMEOUT_MS` wieder herausnehmen **Geprüft:** `tsc` sauber · 295 Unit-Tests grün (vorher 289) · `npm run build` durch · gegengeprobt, dass mit abgeschaltetem Nachschlag vier der sechs neuen Tests fallen und die beiden, die das Ausbleiben prüfen, grün bleiben. **Aufgewendete Zeit:** 00:05 **Pull Request:** #25 Nach Freigabe: `/issue-freigabe 23`
florian.wilde removed the zu-testen label 2026-09-09 22:12:46 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Total Time Spent: 4 minutes
florian.wilde
4 minutes
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: florian.wilde/nebula#23