Skip to content

Commit dc3686b

Browse files
malzilandclaude
andcommitted
Release 1.4.2: Deadline-aware pump + Prefix-Commit + adaptive Chunk-Größe
Fixes nach dem zweiten Dogfood-Restore: Worker starb nach ~160 MB und wartete 6,5 h auf einen Admin-Besuch, weil der synchrone curl_multi-Pump den Tick blockieren konnte, bis PHPs Hard-Limit zuschlug. - download_chunks_parallel() ist jetzt Deadline-bewusst: neuer Parameter \$deadline_ts, Pump pollt nach jedem curl_multi_select() die Restzeit und bricht unfertige Handles mit WP_Error('deadline') ab. - Contiguous-Prefix-Commit im Restore-Tick: erfolgreiche Präfix-Chunks werden auch bei Teilerfolg auf Platte geschrieben, nur der Rest wird im nächsten Tick wiederholt. 3/4 fertig = 3/4 gesichert. - compute_adaptive_limits() skaliert chunk_mb_download jetzt linear mit dem Tick-Budget: clamp(ceil(tick_time × 0.2), 4, 20). 25-s-Tick → 5 MB statt bisher starrer 20 MB, die das Tick-Budget sprengten. - CURLOPT_TIMEOUT gekoppelt an Tick: clamp(tick_time - 3, 15, 90). - Shutdown-Safety-Net via register_shutdown_function() feuert spawn_next_tick() nach, falls ein PHP-Fatal den Tick doch killt — keine 6-h-Lücken mehr, wenn kein Admin auf der Seite ist. - Admin-Seite zeigt die externe Cron-URL mit Crontab-Beispiel für Staging-Server ohne Browser-Traffic. - readme.txt: neuer Abschnitt "Recommended server configuration" — Plugin läuft ab 30 s max_execution_time, ≥60 s empfohlen, ≥180 s optimal. Tests: 61/61 grün. Drei neue Tests für adaptive Chunk-Größe. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 6bc9fb2 commit dc3686b

7 files changed

Lines changed: 356 additions & 98 deletions

File tree

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,26 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.4.2] — 2026-04-17
9+
10+
### Fixed
11+
- **Worker starb nach ~160 MB und wartete 6,5 h auf einen Admin-Besuch**: Im zweiten Dogfood-Restore mit 1.4.1 lieferten die parallelen Batches plötzlich 40–80 MB in 135–180 s (`Langsamer Download-Batch`). Der Pump von `download_chunks_parallel()` war rein synchron — eine 180-s-`CURLOPT_TIMEOUT` konnte den gesamten 25-s-Tick blockieren. Zwei Batches à 140 s sprengten damit das via `@set_time_limit()` gesetzte Budget, PHP schoss den Worker ab, und weil weder `schedule_next_tick()` noch `spawn_next_tick()` je erreicht wurden, blieb die Queue 6,5 h lang stehen — bis zufällig jemand die Admin-Oberfläche öffnete und der Admin-Fallback den Restart auslöste. Der Pump ist jetzt **Deadline-bewusst**: `download_chunks_parallel()` bekommt einen absoluten `deadline_ts`, pollt nach jedem `curl_multi_select()` (max. 0,5 s) die Restzeit und bricht unfertige Handles ab, bevor PHPs Hard-Limit zuschlägt. Abgebrochene Chunks kommen mit `WP_Error('deadline')` zurück und werden sauber verbucht.
12+
- **Erfolgreiche Chunks wurden bei Batch-Fehlern weggeworfen**: Wenn drei von vier Chunks in ~40 s fertig waren und der vierte nach 140 s in 0 bytes lief, warf der Retry-Pfad alle vier Temp-Files weg und startete bei Offset 0 des Batches neu. 120 MB Traffic umsonst, Worker noch näher am Time-Limit. Jetzt **Contiguous-Prefix-Commit**: der längste lückenlose Präfix erfolgreicher Chunks wird auch bei Teilerfolg an die Zieldatei angehängt, der Offset wandert entsprechend weiter. Nur der Rest (ab dem ersten Fehler-Chunk) wird im nächsten Tick wiederholt. Damit ist gesichtet: selbst wenn 3/4 fertig werden, bleiben 3/4 auf Platte.
13+
- **Download-Chunk-Größe ignorierte das Tick-Budget**: Der 20-MB-Default aus 1.4.0 war für 250-s-Ticks richtig, aber für einen 25-s-Tick-Budget-Server zu groß — ein 20-MB-Chunk bei beobachteten 0,3–0,6 MB/s durch Cloudflare Tunnel braucht 30–65 s und sprengt den Tick schon alleine. `compute_adaptive_limits()` skaliert die Chunk-Größe jetzt linear mit dem Tick-Budget: `clamp(ceil(tick_time × 0.2), 4, 20)`. 25-s-Tick → 5 MB, 55-s-Tick → 11 MB, 250-s-Tick → 20 MB (Deckel). Die Parallelität verbraucht bei kleineren Chunks auch weniger RAM, sodass bei 256 MB Memory jetzt 7 statt 4 parallele Streams fahren.
14+
- **`CURLOPT_TIMEOUT` war an Tick-Länge entkoppelt**: Jeder Chunk hatte starre 180 s `CURLOPT_TIMEOUT`, egal wie klein das Tick-Budget war. Jetzt `chunk_timeout = clamp(tick_time - 3, 15, 90)` — bleibt unter Cloudflare Tunnels ~100-s-Fenster und stirbt immer vor dem PHP-Zeitlimit.
15+
16+
### Added
17+
- **Shutdown-Safety-Net gegen PHP-Fatal / Hard-Time-Limit**: `process_restore_tick()` registriert jetzt per `register_shutdown_function()` einen Fallback, der bei einem Fatal-Error (E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR) den Queue-Lock freigibt und `spawn_next_tick()` nachfeuert. Falls der Deadline-aware-Pump mal danebenliegt und PHP den Worker trotzdem killt, wacht der Restore dank des Loopback-Pings wieder auf — nicht erst beim nächsten Admin-Login.
18+
- **Admin-Seite zeigt externe Cron-URL**: Neues Card-Panel „Externer Worker-Heartbeat" mit der schlüsselgeschützten `admin-ajax.php?action=sbu_cron_ping&key=…`-URL plus Crontab-Beispiel (`*/2 * * * * curl -fsS -o /dev/null …`). Für reine Staging-Umgebungen ohne Browser-Traffic ist das der Holzhammer-Weg, um die Loopback-Kette am Leben zu halten, wenn WP-Cron gar nicht erst feuert.
19+
20+
### Changed
21+
- **`SBU_Seafile_API::download_chunks_parallel()` hat einen neuen optionalen Parameter `$deadline_ts`**: absolute `microtime(true)`-Schwelle. Legacy-Aufrufe mit drei Argumenten funktionieren unverändert (Default 0 deaktiviert die Deadline-Logik). Für Tests ist das Verhalten unverändert, für den Restore-Tick kommt der Wert aus `$tick_start + $lim['tick_time'] - 2`.
22+
- **Teil-Batches loggen jetzt INFO statt RETRY**: Wenn ein Batch mit Prefix-Commit weiterkommt, steht im Log `Teilweise erfolgreich (N/M Chunks committed, Rest: Grund)` statt eines roten RETRY-Tokens. Spiegelt die Realität besser: es ist ein Vortschritt, kein Fehler.
23+
24+
### Konstanten
25+
- **Neu**: `SBU_DOWNLOAD_CHUNK_MB_MIN=4` (untere Grenze für die adaptive Chunk-Größe).
26+
- **Geändert**: `SBU_DOWNLOAD_CHUNK_MB_DEFAULT=20` bleibt — ist jetzt explizit nur noch Ceiling (echter Wert aus `compute_adaptive_limits()`).
27+
828
## [1.4.1] — 2026-04-17
929

1030
### Fixed

0 commit comments

Comments
 (0)