v0.24.9 — Deploy _api/, fix WebView2 Program Files, DL robustness
Deploy auto de l'API PHP de stats (parallèle Report/Doc) : - ApiToolDeployer : copy _api/ → C:\xampp\htdocs\proserve\ avec atomic rename + backups horodatés + revert + pruning. Strict clone du pattern DocToolDeployer. - ApiToolConfig dans LocalConfig (default folder "proserve" en minuscule pour matcher l'install standard PROSERVE côté client). - Settings → Avancés : section dédiée (HtdocsRoot, FolderName, AutoDeploy, MaxBackups, Re-déployer, liste backups + revert) + ApiBackupViewModel. - DI registration dans App.xaml.cs, injection MainViewModel, appel post-install après le bloc Doc. - 8 nouvelles strings i18n (5 langues). Fix WebView2 vide en Program Files : - Set WEBVIEW2_USER_DATA_FOLDER vers %LocalAppData%\PSLauncher\WebView2\ dans App.OnStartup. Sans ça, WebView2 essaie d'écrire son cache à côté du .exe (read-only en Program Files) → init silencieusement KO → onglets Report/Doc vides. Refresh auto WebView2 sur navigation d'onglet : - Hook IsVisibleChanged sur ReportWebView et DocsWebView. À chaque ré-affichage, CoreWebView2.Reload() pour voir les données serveur à jour. Le binding Source garde la nav initiale au cold start. Fix UI : Cancel décalant le footer pendant Check updates : - Nouveau flag IsDownloadActive distinct de IsBusy. Visibility du bouton Cancel passe de IsBusy → IsDownloadActive : couvre uniquement les DL, plus aucune apparition pendant Check updates / Install / Uninstall / Self-update qui décalait tout le layout 1 s. DL robustness (multi-PC) : - SafeInstallAsync : error boundary sur l'install handler. Plus aucune exception silencieuse — log + popup d'erreur visible (résout les cas "le 2e PC ne démarre pas, sans message"). - DownloadManager : vérif explicite que CHAQUE segment a Completed=true && DownloadedBytes >= Length AVANT le SHA-256. Le check actualSize était inutile (fichier sparse-préalloué). - MaxRetryAttempts Polly 6 → 10 pour absorber les outages PHP-FPM request_terminate_timeout sous charge multi-PC. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -62,7 +62,11 @@ public sealed class DownloadManager : IDownloadManager
|
||||
_retryPipeline = new ResiliencePipelineBuilder()
|
||||
.AddRetry(new RetryStrategyOptions
|
||||
{
|
||||
MaxRetryAttempts = 6,
|
||||
// 10 tentatives × backoff 1→32s avec jitter ≈ ~3 min de retry budget
|
||||
// par segment. Couvre les outages PHP-FPM courts en multi-PC (où des
|
||||
// segments peuvent être tués mid-stream par request_terminate_timeout)
|
||||
// sans donner l'impression d'une boucle infinie en cas de panne réelle.
|
||||
MaxRetryAttempts = 10,
|
||||
BackoffType = DelayBackoffType.Exponential,
|
||||
Delay = TimeSpan.FromSeconds(1),
|
||||
MaxDelay = TimeSpan.FromSeconds(32),
|
||||
@@ -369,7 +373,22 @@ public sealed class DownloadManager : IDownloadManager
|
||||
_stateStore.Save(state);
|
||||
progress?.Report(new DownloadProgress(state.DownloadedBytes, total, 0, TimeSpan.Zero));
|
||||
|
||||
// 5. Vérif taille
|
||||
// 5. Vérif complétion des segments
|
||||
// Le check `actualSize != total` ci-dessous est INSUFFISANT car le fichier est
|
||||
// pré-alloué en sparse à `total` octets — sa taille filesystem matchera toujours
|
||||
// peu importe ce qui a été écrit. Si un segment a échoué silencieusement (cas
|
||||
// pré-0.24.5 ou bug futur), on aurait des trous (zéros NTFS) → SHA KO en sortie
|
||||
// sans diagnostic clair. On vérifie explicitement que CHAQUE segment a atteint
|
||||
// sa cible AVANT de lancer le SHA-256 (qui prend 30s-3min sur un 14 Go).
|
||||
var incomplete = state.Segments.FirstOrDefault(s => !s.Completed || s.DownloadedBytes < s.Length);
|
||||
if (incomplete is not null)
|
||||
{
|
||||
_stateStore.Save(state); // garde l'état pour permettre un resume manuel
|
||||
throw new InvalidDataException(
|
||||
$"Segment {incomplete.Index} incomplet : {incomplete.DownloadedBytes:N0}/{incomplete.Length:N0} octets " +
|
||||
$"(Completed={incomplete.Completed}). Relance le téléchargement pour reprendre.");
|
||||
}
|
||||
|
||||
var actualSize = new FileInfo(partialPath).Length;
|
||||
if (actualSize != total)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user