v0.19.0 — Bump default parallel segments 8→16 to shorten end-of-DL tail
Issue : on a 14 GB download with 8 segments, when 7 finish there's only 1 connection left handling its assigned 1.75 GB → apparent throughput collapses to 1/8th of the peak for the final stretch (~5 min visible slowdown at the end). Quick fix : double the default segment count. - 8 segments : last has 1.75 GB to finish alone - 16 segments : last has 875 MB → tail ~halved Tuning surfaced in Settings → Avancés → Serveur as « Connexions parallèles pour les téléchargements (1-32, défaut 16) ». Power users on faster servers can push to 24-32. OVH mutualisé tolerates up to 16-24 ; above that, soft rate-limiting kicks in. Aligned : - LocalConfig default : 8 → 16 - DownloadManager clamp : Math.Clamp(_, 1, 16) → 1, 32 - HttpClient handler MaxConnectionsPerServer : 16 → 32 (matches new ceiling) Versions bumped to 0.19.0. Existing config.json files will keep their previous value (8) untouched ; delete config.json to pick up the new default, or just bump it in Settings → Avancés. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -112,16 +112,16 @@ public partial class App : Application
|
||||
services.AddSingleton(sp =>
|
||||
{
|
||||
// Handler tuné pour les gros téléchargements parallèles :
|
||||
// - MaxConnectionsPerServer=16 pour autoriser le multi-segment (8 par défaut).
|
||||
// - AutomaticDecompression sur l'API JSON uniquement (None ici car les builds
|
||||
// sont des ZIPs déjà compressés ; éviter la CPU+RAM gaspillée par un éventuel
|
||||
// wrapping gzip côté serveur).
|
||||
// - MaxConnectionsPerServer=32 pour aligner avec le clamp DownloadManager (8-32).
|
||||
// Default WPF = 8 → trop bas pour notre multi-segment.
|
||||
// - AutomaticDecompression=None : les builds sont des ZIPs déjà compressés ;
|
||||
// éviter la CPU+RAM gaspillée par un éventuel wrapping gzip côté serveur.
|
||||
// - PooledConnectionLifetime court pour éviter qu'OVH ferme nos sockets sous nous.
|
||||
var handler = new SocketsHttpHandler
|
||||
{
|
||||
PooledConnectionLifetime = TimeSpan.FromMinutes(5),
|
||||
PooledConnectionIdleTimeout = TimeSpan.FromSeconds(60),
|
||||
MaxConnectionsPerServer = 16,
|
||||
MaxConnectionsPerServer = 32,
|
||||
EnableMultipleHttp2Connections = true,
|
||||
AutomaticDecompression = System.Net.DecompressionMethods.None,
|
||||
};
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
<Product>PROSERVE Launcher</Product>
|
||||
<Copyright>© 2026 ASTERION VR — All rights reserved</Copyright>
|
||||
<RootNamespace>PSLauncher.App</RootNamespace>
|
||||
<Version>0.18.0</Version>
|
||||
<AssemblyVersion>0.18.0.0</AssemblyVersion>
|
||||
<FileVersion>0.18.0.0</FileVersion>
|
||||
<Version>0.19.0</Version>
|
||||
<AssemblyVersion>0.19.0.0</AssemblyVersion>
|
||||
<FileVersion>0.19.0.0</FileVersion>
|
||||
|
||||
<!-- Single-file self-contained publish profile (used by `dotnet publish`) -->
|
||||
<PublishSingleFile>true</PublishSingleFile>
|
||||
|
||||
@@ -49,6 +49,7 @@ public sealed partial class SettingsViewModel : ObservableObject
|
||||
[ObservableProperty] private string _language;
|
||||
[ObservableProperty] private string _reportUrl;
|
||||
[ObservableProperty] private string _documentationUrl;
|
||||
[ObservableProperty] private int _parallelSegments;
|
||||
|
||||
// ----- DB Migration settings -----
|
||||
[ObservableProperty] private string _dbHost;
|
||||
@@ -173,6 +174,7 @@ public sealed partial class SettingsViewModel : ObservableObject
|
||||
_language = string.IsNullOrWhiteSpace(config.Language) ? "auto" : config.Language;
|
||||
_reportUrl = config.ReportUrl;
|
||||
_documentationUrl = config.DocumentationUrl;
|
||||
_parallelSegments = config.ParallelDownloadSegments;
|
||||
|
||||
_dbHost = config.Database.Host;
|
||||
_dbPort = config.Database.Port;
|
||||
@@ -303,6 +305,7 @@ public sealed partial class SettingsViewModel : ObservableObject
|
||||
_config.Language = Language ?? "auto";
|
||||
_config.ReportUrl = ReportUrl?.Trim() ?? "";
|
||||
_config.DocumentationUrl = DocumentationUrl?.Trim() ?? "";
|
||||
_config.ParallelDownloadSegments = Math.Clamp(ParallelSegments, 1, 32);
|
||||
|
||||
// DB settings
|
||||
_config.Database.Host = DbHost.Trim();
|
||||
|
||||
@@ -230,6 +230,19 @@
|
||||
Background="#1A1A20" Foreground="{StaticResource Brush.Text.Primary}"
|
||||
BorderBrush="{StaticResource Brush.Border}" BorderThickness="1" Padding="8"
|
||||
FontFamily="Consolas" />
|
||||
|
||||
<!-- Connexions parallèles : tuning de la queue de fin de DL -->
|
||||
<TextBlock Text="{x:Static loc:Strings.SettingsParallelSegments}"
|
||||
Foreground="{StaticResource Brush.Text.Secondary}"
|
||||
FontSize="12" Margin="0,16,0,4" />
|
||||
<TextBox Text="{Binding ParallelSegments, UpdateSourceTrigger=PropertyChanged}"
|
||||
Background="#1A1A20" Foreground="{StaticResource Brush.Text.Primary}"
|
||||
BorderBrush="{StaticResource Brush.Border}" BorderThickness="1" Padding="8"
|
||||
Width="80" HorizontalAlignment="Left" />
|
||||
<TextBlock Text="{x:Static loc:Strings.SettingsParallelSegmentsHint}"
|
||||
Foreground="{StaticResource Brush.Text.Secondary}"
|
||||
FontSize="11" FontStyle="Italic" Margin="0,4,0,0"
|
||||
TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
|
||||
@@ -176,7 +176,10 @@ public sealed class DownloadManager : IDownloadManager
|
||||
}
|
||||
|
||||
// 2. Choix single vs multi-segment
|
||||
var requestedSegments = Math.Clamp(_config.ParallelDownloadSegments, 1, 16);
|
||||
// Hard-cap à 32 : au-delà OVH mutualisé risque le rate-limit per-IP et le
|
||||
// gain marginal devient négatif. 16 = défaut, 24-32 OK pour les serveurs
|
||||
// qui le supportent. 1 = comportement single-segment legacy.
|
||||
var requestedSegments = Math.Clamp(_config.ParallelDownloadSegments, 1, 32);
|
||||
var useMultiSegment = requestedSegments > 1
|
||||
&& job.ExpectedSize >= MultiSegmentMinSize
|
||||
&& (existing is null || existing.Segments.Count > 0);
|
||||
|
||||
@@ -177,6 +177,21 @@ public static class Strings
|
||||
$"تعذر تحميل {url}\n\n{detail}\n\nتأكد من تشغيل XAMPP وأن العنوان صحيح (الإعدادات → متقدم)."
|
||||
);
|
||||
|
||||
public static string SettingsParallelSegments => T(
|
||||
"Connexions parallèles pour les téléchargements (1-32, défaut 16)",
|
||||
"Parallel connections for downloads (1-32, default 16)",
|
||||
"下载的并行连接数 (1-32,默认 16)",
|
||||
"การเชื่อมต่อแบบขนานสำหรับการดาวน์โหลด (1-32, ค่าเริ่มต้น 16)",
|
||||
"اتصالات متوازية للتنزيلات (1-32، الافتراضي 16)"
|
||||
);
|
||||
public static string SettingsParallelSegmentsHint => T(
|
||||
"Plus de connexions = débit pic plus élevé et queue de fin de DL plus courte. Au-delà de 16 le serveur peut throttler.",
|
||||
"More connections = higher peak throughput and shorter end-of-DL tail. Above 16 the server may throttle.",
|
||||
"更多连接 = 更高的峰值吞吐量和更短的下载尾部。超过 16 服务器可能会限速。",
|
||||
"การเชื่อมต่อมากขึ้น = ปริมาณงานสูงสุดมากขึ้นและส่วนท้ายของการดาวน์โหลดสั้นลง สูงกว่า 16 เซิร์ฟเวอร์อาจจำกัด",
|
||||
"اتصالات أكثر = إنتاجية ذروة أعلى وذيل تنزيل أقصر. فوق 16 قد يقيّد الخادم."
|
||||
);
|
||||
|
||||
public static string SettingsAdvanced => T(
|
||||
"▸ PARAMÈTRES AVANCÉS (serveur, installation, base de données, logs)",
|
||||
"▸ ADVANCED SETTINGS (server, installation, database, logs)",
|
||||
|
||||
@@ -16,9 +16,13 @@ public sealed class LocalConfig
|
||||
/// <summary>
|
||||
/// Nombre de connexions HTTP parallèles utilisées pour télécharger un build.
|
||||
/// 1 = comportement legacy single-connection. 4-8 contourne le throttling
|
||||
/// per-connection d'Apache/OVH mutualisé. 8 est un bon défaut.
|
||||
/// per-connection d'Apache/OVH mutualisé. 16 = défaut depuis v0.19 pour
|
||||
/// raccourcir la « queue » en fin de DL : avec 8 segments sur 14 Go, le
|
||||
/// dernier segment doit finir seul ~1.75 Go (visible comme un effondrement
|
||||
/// du débit en fin de course) ; avec 16, c'est ~875 Mo. Push à 24/32 si
|
||||
/// ton serveur l'accepte (OVH mutualisé tient bien jusqu'à 16-24).
|
||||
/// </summary>
|
||||
public int ParallelDownloadSegments { get; set; } = 8;
|
||||
public int ParallelDownloadSegments { get; set; } = 16;
|
||||
|
||||
/// <summary>
|
||||
/// Si false, ignore la vérification SHA-256 même si le manifest l'exige.
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<LangVersion>latest</LangVersion>
|
||||
<AssemblyName>PS_Launcher.Updater</AssemblyName>
|
||||
<RootNamespace>PSLauncher.Updater</RootNamespace>
|
||||
<Version>0.18.0</Version>
|
||||
<Version>0.19.0</Version>
|
||||
<ApplicationIcon>..\PSLauncher.App\Resources\favicon.ico</ApplicationIcon>
|
||||
<Company>ASTERION VR</Company>
|
||||
<Copyright>© 2026 ASTERION VR — All rights reserved</Copyright>
|
||||
|
||||
Reference in New Issue
Block a user