diff --git a/CHANGELOG.md b/CHANGELOG.md
index ce9e4d3..b5dad9f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [1.9.4] - 2021-10-28
+### Changed
+- Fixed issues retrying torrents after multiple failed downloads in large torrents.
+
## [1.9.3] - 2021-10-27
### Changed
- Fixed issue with the unpack queue.
diff --git a/client/src/app/navbar/navbar.component.html b/client/src/app/navbar/navbar.component.html
index 753aeb7..a4e9317 100644
--- a/client/src/app/navbar/navbar.component.html
+++ b/client/src/app/navbar/navbar.component.html
@@ -55,7 +55,7 @@
Profile
Logout
- Version 1.9.3
+ Version 1.9.4
diff --git a/package.json b/package.json
index b5c7831..d373624 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "rdt-client",
- "version": "1.9.3",
+ "version": "1.9.4",
"description": "This is a web interface to manage your torrents on Real-Debrid.",
"main": "index.js",
"dependencies": {
diff --git a/server/RdtClient.Service/Services/DownloadClient.cs b/server/RdtClient.Service/Services/DownloadClient.cs
index 128cb21..622bed8 100644
--- a/server/RdtClient.Service/Services/DownloadClient.cs
+++ b/server/RdtClient.Service/Services/DownloadClient.cs
@@ -90,6 +90,9 @@ namespace RdtClient.Service.Services
public async Task Cancel()
{
+ Finished = true;
+ Error = null;
+
if (Downloader == null)
{
return;
diff --git a/server/RdtClient.Service/Services/Downloaders/Aria2cDownloader.cs b/server/RdtClient.Service/Services/Downloaders/Aria2cDownloader.cs
index dae8410..81cc464 100644
--- a/server/RdtClient.Service/Services/Downloaders/Aria2cDownloader.cs
+++ b/server/RdtClient.Service/Services/Downloaders/Aria2cDownloader.cs
@@ -168,6 +168,10 @@ namespace RdtClient.Service.Services.Downloaders
if (download == null)
{
+ DownloadComplete?.Invoke(this, new DownloadCompleteEventArgs
+ {
+ Error = $"Download was not found in Aria2"
+ });
return;
}
diff --git a/server/RdtClient.Service/Services/TorrentRunner.cs b/server/RdtClient.Service/Services/TorrentRunner.cs
index 98cf0f1..58af329 100644
--- a/server/RdtClient.Service/Services/TorrentRunner.cs
+++ b/server/RdtClient.Service/Services/TorrentRunner.cs
@@ -4,9 +4,11 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
+using System.Threading;
using System.Threading.Tasks;
using System.Web;
using Aria2NET;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using RdtClient.Data.Enums;
@@ -27,15 +29,19 @@ namespace RdtClient.Service.Services
public static readonly ConcurrentDictionary ActiveDownloadClients = new();
public static readonly ConcurrentDictionary ActiveUnpackClients = new();
+ public static readonly SemaphoreSlim TorrentResetLock = new(1, 1);
+
private readonly ILogger _logger;
+ private readonly IServiceProvider _serviceProvider;
private readonly Torrents _torrents;
private readonly Downloads _downloads;
private readonly RemoteService _remoteService;
private readonly HttpClient _httpClient;
- public TorrentRunner(ILogger logger, Torrents torrents, Downloads downloads, RemoteService remoteService)
+ public TorrentRunner(ILogger logger, IServiceProvider serviceProvider, Torrents torrents, Downloads downloads, RemoteService remoteService)
{
_logger = logger;
+ _serviceProvider = serviceProvider;
_torrents = torrents;
_downloads = downloads;
_remoteService = remoteService;
@@ -185,9 +191,17 @@ namespace RdtClient.Service.Services
{
Log($"Retrying torrent", download, download.Torrent);
- await _torrents.RetryTorrent(download.TorrentId, download.Torrent.RetryCount + 1);
+ _ = Task.Run(async () =>
+ {
+ using var blockScope = _serviceProvider.CreateScope();
+ var torrentsService = (Torrents) blockScope.ServiceProvider.GetService(typeof(Torrents));
+ await torrentsService.RetryTorrent(download.TorrentId, download.Torrent.RetryCount + 1);
+ });
- continue;
+ // Force a delay and return the main loop to prevent concurrency issues.
+ await Task.Delay(10000);
+
+ return;
}
else
{
@@ -468,8 +482,17 @@ namespace RdtClient.Service.Services
{
Log($"Retrying torrent", torrent);
- await _torrents.RetryTorrent(torrent.TorrentId, torrent.RetryCount + 1);
- continue;
+ _ = Task.Run(async () =>
+ {
+ using var blockScope = _serviceProvider.CreateScope();
+ var torrentsService = (Torrents) blockScope.ServiceProvider.GetService(typeof(Torrents));
+ await torrentsService.RetryTorrent(torrent.TorrentId, torrent.RetryCount + 1);
+ });
+
+ // Force a delay and return the main loop to prevent concurrency issues.
+ await Task.Delay(10000);
+
+ return;
}
Log($"Received RealDebrid error: {torrent.RdStatusRaw}, not processing further", torrent);
diff --git a/server/RdtClient.Service/Services/Torrents.cs b/server/RdtClient.Service/Services/Torrents.cs
index 35d0896..7124414 100644
--- a/server/RdtClient.Service/Services/Torrents.cs
+++ b/server/RdtClient.Service/Services/Torrents.cs
@@ -27,6 +27,8 @@ namespace RdtClient.Service.Services
private readonly ITorrentClient _torrentClient;
+ public static readonly SemaphoreSlim TorrentResetLock = new(1, 1);
+
public Torrents(ILogger logger,
TorrentData torrentData,
Downloads downloads,
@@ -219,6 +221,8 @@ namespace RdtClient.Service.Services
Log($"Deleting", torrent);
+ await UpdateComplete(torrentId, DateTimeOffset.UtcNow);
+
foreach (var download in torrent.Downloads)
{
while (TorrentRunner.ActiveDownloadClients.TryGetValue(download.DownloadId, out var downloadClient))
@@ -359,59 +363,82 @@ namespace RdtClient.Service.Services
public async Task RetryTorrent(Guid torrentId, Int32 retryCount)
{
- var torrent = await _torrentData.GetById(torrentId);
+ await TorrentResetLock.WaitAsync();
- if (torrent == null)
+ try
{
- return;
- }
+ var torrent = await _torrentData.GetById(torrentId);
- Log($"Retrying Torrent", torrent);
-
- foreach (var download in torrent.Downloads)
- {
- while (TorrentRunner.ActiveDownloadClients.TryGetValue(download.DownloadId, out var downloadClient))
+ if (torrent == null)
{
- await downloadClient.Cancel();
-
- await Task.Delay(100);
+ return;
}
- while (TorrentRunner.ActiveUnpackClients.TryGetValue(download.DownloadId, out var unpackClient))
+ Log($"Retrying Torrent", torrent);
+
+ await UpdateComplete(torrent.TorrentId, DateTimeOffset.Now);
+
+ foreach (var download in torrent.Downloads)
{
- unpackClient.Cancel();
-
- await Task.Delay(100);
+ await _downloads.UpdateError(download.DownloadId, null);
+ await _downloads.UpdateCompleted(download.DownloadId, DateTimeOffset.Now);
}
+
+ foreach (var download in torrent.Downloads)
+ {
+ while (TorrentRunner.ActiveDownloadClients.TryGetValue(download.DownloadId, out var downloadClient))
+ {
+ await downloadClient.Cancel();
+
+ await Task.Delay(100);
+ }
+
+ while (TorrentRunner.ActiveUnpackClients.TryGetValue(download.DownloadId, out var unpackClient))
+ {
+ unpackClient.Cancel();
+
+ await Task.Delay(100);
+ }
+ }
+
+ await Delete(torrentId, true, true, true);
+
+ if (String.IsNullOrWhiteSpace(torrent.FileOrMagnet))
+ {
+ throw new Exception($"Cannot re-add this torrent, original magnet or file not found");
+ }
+
+ Torrent newTorrent;
+
+ if (torrent.IsFile)
+ {
+ var bytes = Convert.FromBase64String(torrent.FileOrMagnet);
+
+ newTorrent = await UploadFile(bytes,
+ torrent.Category,
+ torrent.DownloadAction,
+ torrent.FinishedAction,
+ torrent.DownloadMinSize,
+ torrent.DownloadManualFiles,
+ torrent.Priority);
+ }
+ else
+ {
+ newTorrent = await UploadMagnet(torrent.FileOrMagnet,
+ torrent.Category,
+ torrent.DownloadAction,
+ torrent.FinishedAction,
+ torrent.DownloadMinSize,
+ torrent.DownloadManualFiles,
+ torrent.Priority);
+ }
+
+ await _torrentData.UpdateRetryCount(newTorrent.TorrentId, retryCount);
}
-
- await Delete(torrentId, true, true, true);
-
- if (String.IsNullOrWhiteSpace(torrent.FileOrMagnet))
+ finally
{
- throw new Exception($"Cannot re-add this torrent, original magnet or file not found");
+ TorrentResetLock.Release();
}
-
- Torrent newTorrent;
-
- if (torrent.IsFile)
- {
- var bytes = Convert.FromBase64String(torrent.FileOrMagnet);
-
- newTorrent = await UploadFile(bytes, torrent.Category, torrent.DownloadAction, torrent.FinishedAction, torrent.DownloadMinSize, torrent.DownloadManualFiles, torrent.Priority);
- }
- else
- {
- newTorrent = await UploadMagnet(torrent.FileOrMagnet,
- torrent.Category,
- torrent.DownloadAction,
- torrent.FinishedAction,
- torrent.DownloadMinSize,
- torrent.DownloadManualFiles,
- torrent.Priority);
- }
-
- await _torrentData.UpdateRetryCount(newTorrent.TorrentId, retryCount);
}
public async Task RetryDownload(Guid downloadId)
diff --git a/server/RdtClient.Web/RdtClient.Web.csproj b/server/RdtClient.Web/RdtClient.Web.csproj
index d9c2e86..e0377fa 100644
--- a/server/RdtClient.Web/RdtClient.Web.csproj
+++ b/server/RdtClient.Web/RdtClient.Web.csproj
@@ -4,7 +4,7 @@
net5.0
Exe
94c24cba-f03f-4453-a671-3640b517c573
- 1.9.3
+ 1.9.4