Skip to content

Conversation

@omgbeez
Copy link

@omgbeez omgbeez commented Jan 10, 2026

User description

Also remove try catch around progress calculations, and instead change calculation to guarantee safety of values/operations.


PR Type

Enhancement


Description

  • Add ETA calculation for torrents based on progress and elapsed time

  • Replace try-catch with safe Math.Clamp for progress calculations

  • Improve null-safety checks using pattern matching

  • Calculate remaining time using combined RD and download progress


Diagram Walkthrough

flowchart LR
  A["Torrent Progress Data"] --> B["Safe Progress Calculation"]
  B --> C["Calculate Combined Progress"]
  C --> D["Compute ETA from Elapsed Time"]
  D --> E["Return TorrentInfo with ETA"]
Loading

File Walkthrough

Relevant files
Enhancement
QBittorrent.cs
Add ETA calculation and improve progress safety                   

server/RdtClient.Service/Services/QBittorrent.cs

  • Removed try-catch block around progress calculations and replaced with
    Math.Clamp for safe value clamping
  • Added ETA calculation logic that computes remaining time based on
    combined RD and download progress
  • Improved null-safety checks using pattern matching (e.g.,
    torrent.Downloads is { Count: > 0 })
  • Changed Eta field from hardcoded 0 to calculated
    (Int64)remaining.TotalSeconds
  • Refactored progress calculation to use Math.Clamp for ensuring values
    stay within valid ranges
+18/-27 

@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Jan 10, 2026

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

🔴
Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
ETA edge cases: The new ETA calculation can produce invalid values (e.g., negative or overflowed
remaining/Eta) due to unchecked clock skew and unbounded (elapsed.Ticks / progress) when
progress is very small.

Referred Code
var remaining = TimeSpan.Zero;
if (progress > 0 && progress < 1.0)
{
    var startTime = torrent.Retry > torrent.Added ? torrent.Retry.Value : torrent.Added;
    var elapsed = DateTimeOffset.UtcNow - startTime;
    var totalEstimatedTime = TimeSpan.FromTicks((Int64)(elapsed.Ticks / progress));
    remaining = totalEstimatedTime - elapsed;
}

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link
Contributor

qodo-code-review bot commented Jan 10, 2026

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
General
Improve ETA calculation using current speed

Refactor the ETA calculation to use the current download speed and remaining
bytes for a more accurate and responsive estimate.

server/RdtClient.Service/Services/QBittorrent.cs [233-241]

 var progress = (rdProgress + downloadProgress) / 2.0;
 var remaining = TimeSpan.Zero;
-if (progress > 0 && progress < 1.0)
+var bytesRemaining = bytesTotal - bytesDone;
+if (speed > 0 && bytesRemaining > 0)
 {
-    var startTime = torrent.Retry > torrent.Added ? torrent.Retry.Value : torrent.Added;
-    var elapsed = DateTimeOffset.UtcNow - startTime;
-    var totalEstimatedTime = TimeSpan.FromTicks((Int64)(elapsed.Ticks / progress));
-    remaining = totalEstimatedTime - elapsed;
+    remaining = TimeSpan.FromSeconds(bytesRemaining / (Double)speed);
 }
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: The suggestion proposes a more conventional and accurate method for ETA calculation, using current speed and remaining data, which significantly improves the quality of the new feature.

Medium
Remove redundant TakeWhile call

Remove the redundant TakeWhile(m => true) from the foreach loop and iterate
directly over the allTorrents collection to simplify the code.

server/RdtClient.Service/Services/QBittorrent.cs [197]

-foreach (var torrent in allTorrents.TakeWhile(m => true))
+foreach (var torrent in allTorrents)
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why: The suggestion correctly identifies that TakeWhile(m => true) is redundant and confusing, and its removal simplifies the code without changing functionality.

Low
Remove redundant collection check before averaging

Remove the redundant torrent.Downloads.Any() check before calling Average(), as
the collection is already guaranteed to be non-empty.

server/RdtClient.Service/Services/QBittorrent.cs [229]

-speed = (Int32) (torrent.Downloads.Any() ? torrent.Downloads.Average(m => m.Speed) : 0);
+speed = (Int32) torrent.Downloads.Average(m => m.Speed);
  • Apply / Chat
Suggestion importance[1-10]: 5

__

Why: The suggestion correctly identifies and removes a redundant Any() check, simplifying the code and improving readability.

Low
Possible issue
Prevent negative ETA values

Prevent negative ETA values by clamping the calculated remaining.TotalSeconds to
a minimum of zero.

server/RdtClient.Service/Services/QBittorrent.cs [257]

-Eta = (Int64)remaining.TotalSeconds
+Eta = Math.Max(0L, (Int64)remaining.TotalSeconds)

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 4

__

Why: The suggestion correctly points out that the calculated remaining time could be negative and proposes a simple fix to prevent negative ETA values, improving the robustness of the new logic.

Low
  • Update

@omgbeez omgbeez force-pushed the upstream/qbt-eta branch 3 times, most recently from 08bcf2f to 68cbf18 Compare January 10, 2026 22:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant