Fix: "Jetzt ausführen" wirkte bei character_sync wie ein No-Op #32

Merged
DasAoD merged 1 commit from fix-cron-manual-run-feedback into main 2026-08-20 20:43:39 +02:00
Owner

Befund

Der Job selbst lief einwandfrei — im Activity-Log auf dns1 steht genau dein Klick von heute:

[2026-08-20 20:32:51] Cron manuell gestartet | {"Job":"character_sync","User":"daniele"}
[2026-08-20 20:34:49] Cron-Job | {"Job":"character_sync","Status":"success","Ergebnis":"5/5 erfolgreich"}

Button geklickt → ~2 Minuten später erfolgreich durchgelaufen (5/5 Gilden). Der Bug steckte rein im Frontend.

Root Cause

runCronJobNow() in public/assets/js/admin.js hat nach dem Start des (asynchronen) Jobs nur 3 Sekunden gewartet, dann die Job-Liste neu geladen und das Overlay geschlossen. character_sync läuft aber sequenziell über alle Gilden und kann — wie hier — locker ~2 Minuten brauchen. Nach 3 Sekunden zeigte "Letzter Lauf" also noch den alten Zeitstempel vom vorherigen Lauf, das Overlay verschwand, und es sah aus, als wäre nichts passiert — obwohl der Job brav im Hintergrund weiterlief und kurz danach erfolgreich fertig wurde.

Fix

  • runCronJobNow() merkt sich jetzt den last_run_at-Stand vor dem Start und pollt danach alle 4s (bis zu 5 Minuten) /api/admin_cron.php, bis sich der Zeitstempel tatsächlich ändert — erst dann werden Overlay geschlossen, Liste aktualisiert und das echte Ergebnis angezeigt. Dauert es doch mal länger als 5 Minuten, gibt's stattdessen einen Hinweis, dass der Job noch im Hintergrund läuft, statt unendlich zu warten.
  • Nebenbei gefunden: der Fehler-Zweig hat d.message gelesen, jsonError() setzt aber immer error — eine echte Fehlermeldung (z.B. "Job läuft bereits") wäre bisher nur als "Fehler: Unbekannt" angezeigt worden. Auch gefixt.
  • includes/template.php: JS-Cache-Version gebumpt, da admin.js sich geändert hat.

Getestet

node --check auf der JS-Datei, php -l auf template.php. Die eigentliche Job-Logik (Cron-Runner, Rate-Limiting, Lock-Datei) war nie das Problem und wurde nicht angefasst.

🤖 Generated with Claude Code

## Befund Der Job selbst lief einwandfrei — im Activity-Log auf dns1 steht genau dein Klick von heute: ``` [2026-08-20 20:32:51] Cron manuell gestartet | {"Job":"character_sync","User":"daniele"} [2026-08-20 20:34:49] Cron-Job | {"Job":"character_sync","Status":"success","Ergebnis":"5/5 erfolgreich"} ``` Button geklickt → ~2 Minuten später erfolgreich durchgelaufen (5/5 Gilden). Der Bug steckte rein im Frontend. ## Root Cause `runCronJobNow()` in `public/assets/js/admin.js` hat nach dem Start des (asynchronen) Jobs nur **3 Sekunden** gewartet, dann die Job-Liste neu geladen und das Overlay geschlossen. `character_sync` läuft aber sequenziell über alle Gilden und kann — wie hier — locker ~2 Minuten brauchen. Nach 3 Sekunden zeigte "Letzter Lauf" also noch den **alten** Zeitstempel vom vorherigen Lauf, das Overlay verschwand, und es sah aus, als wäre nichts passiert — obwohl der Job brav im Hintergrund weiterlief und kurz danach erfolgreich fertig wurde. ## Fix - `runCronJobNow()` merkt sich jetzt den `last_run_at`-Stand vor dem Start und pollt danach alle 4s (bis zu 5 Minuten) `/api/admin_cron.php`, bis sich der Zeitstempel tatsächlich ändert — erst dann werden Overlay geschlossen, Liste aktualisiert und das echte Ergebnis angezeigt. Dauert es doch mal länger als 5 Minuten, gibt's stattdessen einen Hinweis, dass der Job noch im Hintergrund läuft, statt unendlich zu warten. - Nebenbei gefunden: der Fehler-Zweig hat `d.message` gelesen, `jsonError()` setzt aber immer `error` — eine echte Fehlermeldung (z.B. "Job läuft bereits") wäre bisher nur als "Fehler: Unbekannt" angezeigt worden. Auch gefixt. - `includes/template.php`: JS-Cache-Version gebumpt, da `admin.js` sich geändert hat. ## Getestet `node --check` auf der JS-Datei, `php -l` auf `template.php`. Die eigentliche Job-Logik (Cron-Runner, Rate-Limiting, Lock-Datei) war nie das Problem und wurde nicht angefasst. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
User reported clicking the manual-run button for "Charakterdaten
synchronisieren" (~20:32/20:33) and seeing no effect. Server-side logs
show it actually ran and completed successfully:

  [2026-08-20 20:32:51] Cron manuell gestartet | {"Job":"character_sync",...}
  [2026-08-20 20:34:49] Cron-Job | {"Job":"character_sync","Status":"success","Ergebnis":"5/5 erfolgreich"}

Root cause was purely in the frontend: runCronJobNow()'s success path
did `setTimeout(() => loadCronJobs(), 3000)` — a fixed 3s delay before
refreshing the displayed "Letzter Lauf" status and hiding the overlay.
character_sync runs the sync sequentially across every guild and can
easily take ~2 minutes (as it did here), so at the 3s mark the job was
still running in the background - the UI just showed the *previous*
run's stale timestamp and made it look like the click had no effect,
when it was actually still working.

Fixed public/assets/js/admin.js: capture the job's last_run_at before
starting, then poll /api/admin_cron.php every 4s (up to 5 minutes)
until it actually changes, and only then show the real result message
and refresh the job list. Falls back to a "still running in the
background" message if it somehow takes longer than 5 minutes, rather
than hanging indefinitely.

Also fixed an adjacent bug in the same function noticed while reading
it: the error branch read `d.message`, but jsonError() always sets the
`error` key - a real failure (e.g. "Job läuft bereits") would have
shown as "Fehler: Unbekannt" instead of the actual reason.

Bumped includes/template.php's JS cache-version constant since
admin.js changed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
DasAoD merged commit badfdd820a into main 2026-08-20 20:43:39 +02:00
Sign in to join this conversation.
No description provided.