From 680c6ba3b4ce453c9159f17c1fd8b58d429d9833 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 11 Feb 2026 16:14:14 +0000 Subject: [PATCH 1/4] Initial plan From bbaaf7cde5dc54a36f711e9839f7340249e908c8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 11 Feb 2026 16:16:32 +0000 Subject: [PATCH 2/4] Address code review comments Co-authored-by: codegefluester <203914+codegefluester@users.noreply.github.com> --- GamesDat.Demo/Program.cs | 43 +++++++++++++------ .../Sources/HttpPollingSourceBase.cs | 27 ++++++++++-- .../Sources/HttpPollingSourceOptions.cs | 4 ++ docs/WarThunder.md | 4 +- 4 files changed, 60 insertions(+), 18 deletions(-) diff --git a/GamesDat.Demo/Program.cs b/GamesDat.Demo/Program.cs index e0bca59..dfa87af 100644 --- a/GamesDat.Demo/Program.cs +++ b/GamesDat.Demo/Program.cs @@ -21,26 +21,43 @@ static async Task Main(string[] args) static async Task CaptureWarThunderSession() { var cts = new CancellationTokenSource(); - Console.CancelKeyPress += (s, e) => + ConsoleCancelEventHandler handler = (s, e) => { e.Cancel = true; cts.Cancel(); }; + Console.CancelKeyPress += handler; - var session = new GameSession() - .AddSource( - WarThunderSources.CreateStateSource() - .UseWriter(new BinarySessionWriter()) - .OutputTo($"./sessions/warthunder_{DateTime.UtcNow:yyyyMMdd_HHmmss}.bin")) - .OnData(data => - { - Console.WriteLine($"Altitude: {data.Altitude} | Speed {data.TrueAirspeed} | Throttle {data.Throttle}"); - }); + try + { + var session = new GameSession() + .AddSource( + WarThunderSources.CreateStateSource() + .UseWriter(new BinarySessionWriter()) + .OutputTo($"./sessions/warthunder_{DateTime.UtcNow:yyyyMMdd_HHmmss}.bin")) + .OnData(data => + { + Console.WriteLine($"Altitude: {data.Altitude} | Speed {data.TrueAirspeed} | Throttle {data.Throttle}"); + }); - await session.StartAsync(cts.Token); + await session.StartAsync(cts.Token); - // Session is now running, wait for cancellation - await Task.Delay(Timeout.Infinite, cts.Token); + // Session is now running, wait for cancellation + await Task.Delay(Timeout.Infinite, cts.Token); + } + catch (FileNotFoundException) + { + Console.WriteLine("\nError: War Thunder is not running. Start War Thunder and try again."); + } + catch (OperationCanceledException) + { + Console.WriteLine("\nCapture stopped by user."); + } + finally + { + Console.CancelKeyPress -= handler; + cts.Dispose(); + } } #endregion diff --git a/GamesDat/Telemetry/Sources/HttpPollingSourceBase.cs b/GamesDat/Telemetry/Sources/HttpPollingSourceBase.cs index 440e037..d475c08 100644 --- a/GamesDat/Telemetry/Sources/HttpPollingSourceBase.cs +++ b/GamesDat/Telemetry/Sources/HttpPollingSourceBase.cs @@ -98,10 +98,31 @@ public override async IAsyncEnumerable ReadContinuousAsync( // JSON parse errors are logged but don't trigger aggressive retry Console.WriteLine($"[{GetType().Name}] JSON parse error (skipping frame): {ex.Message}"); } - catch (OperationCanceledException) + catch (OperationCanceledException ex) { - // Clean cancellation - yield break; + if (cancellationToken.IsCancellationRequested) + { + // Clean cancellation requested by caller + yield break; + } + + // Treat other cancellations (e.g., request timeouts) as connection/timeout errors + _consecutiveErrors++; + + if (firstError) + { + Console.WriteLine($"[{GetType().Name}] Connection error: {ex.Message}"); + Console.WriteLine($"[{GetType().Name}] Retrying with exponential backoff..."); + firstError = false; + } + + if (_consecutiveErrors >= _options.MaxConsecutiveErrors) + { + errorToThrow = new InvalidOperationException( + $"Failed to connect after {_consecutiveErrors} consecutive attempts. " + + $"Ensure the game is running and the API is accessible at {fullUrl}", + ex); + } } catch (Exception ex) when (ex is HttpRequestException or TaskCanceledException) { diff --git a/GamesDat/Telemetry/Sources/HttpPollingSourceOptions.cs b/GamesDat/Telemetry/Sources/HttpPollingSourceOptions.cs index a9eca37..92422d3 100644 --- a/GamesDat/Telemetry/Sources/HttpPollingSourceOptions.cs +++ b/GamesDat/Telemetry/Sources/HttpPollingSourceOptions.cs @@ -1,3 +1,7 @@ +using System; +using System.Collections.Generic; +using System.Linq; + namespace GamesDat.Core.Telemetry.Sources; /// diff --git a/docs/WarThunder.md b/docs/WarThunder.md index 45d4c43..96de098 100644 --- a/docs/WarThunder.md +++ b/docs/WarThunder.md @@ -370,5 +370,5 @@ War Thunder API documentation and community tools: ## See Also - [Creating Custom Sources](CREATING_SOURCES.md) -- [GameSession API Reference](API_REFERENCE.md) -- [Performance Tuning Guide](PERFORMANCE.md) +- GameSession API Reference (coming soon) +- Performance Tuning Guide (coming soon) From fc590d089d30b316cf33dad8613023f19d56a910 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 11 Feb 2026 16:21:17 +0000 Subject: [PATCH 3/4] Remove redundant TaskCanceledException catch Co-authored-by: codegefluester <203914+codegefluester@users.noreply.github.com> --- GamesDat/Telemetry/Sources/HttpPollingSourceBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GamesDat/Telemetry/Sources/HttpPollingSourceBase.cs b/GamesDat/Telemetry/Sources/HttpPollingSourceBase.cs index d475c08..d0930c3 100644 --- a/GamesDat/Telemetry/Sources/HttpPollingSourceBase.cs +++ b/GamesDat/Telemetry/Sources/HttpPollingSourceBase.cs @@ -124,7 +124,7 @@ public override async IAsyncEnumerable ReadContinuousAsync( ex); } } - catch (Exception ex) when (ex is HttpRequestException or TaskCanceledException) + catch (HttpRequestException ex) { // Connection/timeout errors - use exponential backoff _consecutiveErrors++; From cec50483475588d81540fdbc89b0c91f5ac369c1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 11 Feb 2026 16:22:01 +0000 Subject: [PATCH 4/4] Clarify timeout cancellation comment Co-authored-by: codegefluester <203914+codegefluester@users.noreply.github.com> --- GamesDat/Telemetry/Sources/HttpPollingSourceBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GamesDat/Telemetry/Sources/HttpPollingSourceBase.cs b/GamesDat/Telemetry/Sources/HttpPollingSourceBase.cs index d0930c3..561bc3c 100644 --- a/GamesDat/Telemetry/Sources/HttpPollingSourceBase.cs +++ b/GamesDat/Telemetry/Sources/HttpPollingSourceBase.cs @@ -106,7 +106,7 @@ public override async IAsyncEnumerable ReadContinuousAsync( yield break; } - // Treat other cancellations (e.g., request timeouts) as connection/timeout errors + // Timeout cancellation from linkedCts (request timeout) - treat as connection error _consecutiveErrors++; if (firstError)