Fixed issues with retrying and cancelling torrents.
This commit is contained in:
parent
799316413a
commit
0d5d28483b
8 changed files with 111 additions and 50 deletions
|
|
@ -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/),
|
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).
|
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
|
## [1.9.3] - 2021-10-27
|
||||||
### Changed
|
### Changed
|
||||||
- Fixed issue with the unpack queue.
|
- Fixed issue with the unpack queue.
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@
|
||||||
<a class="navbar-item"> Profile </a>
|
<a class="navbar-item"> Profile </a>
|
||||||
<a class="navbar-item" (click)="logout()"> Logout </a>
|
<a class="navbar-item" (click)="logout()"> Logout </a>
|
||||||
<hr class="navbar-divider" />
|
<hr class="navbar-divider" />
|
||||||
<div class="navbar-item">Version 1.9.3</div>
|
<div class="navbar-item">Version 1.9.4</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "rdt-client",
|
"name": "rdt-client",
|
||||||
"version": "1.9.3",
|
"version": "1.9.4",
|
||||||
"description": "This is a web interface to manage your torrents on Real-Debrid.",
|
"description": "This is a web interface to manage your torrents on Real-Debrid.",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,9 @@ namespace RdtClient.Service.Services
|
||||||
|
|
||||||
public async Task Cancel()
|
public async Task Cancel()
|
||||||
{
|
{
|
||||||
|
Finished = true;
|
||||||
|
Error = null;
|
||||||
|
|
||||||
if (Downloader == null)
|
if (Downloader == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -168,6 +168,10 @@ namespace RdtClient.Service.Services.Downloaders
|
||||||
|
|
||||||
if (download == null)
|
if (download == null)
|
||||||
{
|
{
|
||||||
|
DownloadComplete?.Invoke(this, new DownloadCompleteEventArgs
|
||||||
|
{
|
||||||
|
Error = $"Download was not found in Aria2"
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,11 @@ using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using Aria2NET;
|
using Aria2NET;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using RdtClient.Data.Enums;
|
using RdtClient.Data.Enums;
|
||||||
|
|
@ -27,15 +29,19 @@ namespace RdtClient.Service.Services
|
||||||
public static readonly ConcurrentDictionary<Guid, DownloadClient> ActiveDownloadClients = new();
|
public static readonly ConcurrentDictionary<Guid, DownloadClient> ActiveDownloadClients = new();
|
||||||
public static readonly ConcurrentDictionary<Guid, UnpackClient> ActiveUnpackClients = new();
|
public static readonly ConcurrentDictionary<Guid, UnpackClient> ActiveUnpackClients = new();
|
||||||
|
|
||||||
|
public static readonly SemaphoreSlim TorrentResetLock = new(1, 1);
|
||||||
|
|
||||||
private readonly ILogger<TorrentRunner> _logger;
|
private readonly ILogger<TorrentRunner> _logger;
|
||||||
|
private readonly IServiceProvider _serviceProvider;
|
||||||
private readonly Torrents _torrents;
|
private readonly Torrents _torrents;
|
||||||
private readonly Downloads _downloads;
|
private readonly Downloads _downloads;
|
||||||
private readonly RemoteService _remoteService;
|
private readonly RemoteService _remoteService;
|
||||||
private readonly HttpClient _httpClient;
|
private readonly HttpClient _httpClient;
|
||||||
|
|
||||||
public TorrentRunner(ILogger<TorrentRunner> logger, Torrents torrents, Downloads downloads, RemoteService remoteService)
|
public TorrentRunner(ILogger<TorrentRunner> logger, IServiceProvider serviceProvider, Torrents torrents, Downloads downloads, RemoteService remoteService)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_serviceProvider = serviceProvider;
|
||||||
_torrents = torrents;
|
_torrents = torrents;
|
||||||
_downloads = downloads;
|
_downloads = downloads;
|
||||||
_remoteService = remoteService;
|
_remoteService = remoteService;
|
||||||
|
|
@ -185,9 +191,17 @@ namespace RdtClient.Service.Services
|
||||||
{
|
{
|
||||||
Log($"Retrying torrent", download, download.Torrent);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -468,8 +482,17 @@ namespace RdtClient.Service.Services
|
||||||
{
|
{
|
||||||
Log($"Retrying torrent", torrent);
|
Log($"Retrying torrent", torrent);
|
||||||
|
|
||||||
await _torrents.RetryTorrent(torrent.TorrentId, torrent.RetryCount + 1);
|
_ = Task.Run(async () =>
|
||||||
continue;
|
{
|
||||||
|
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);
|
Log($"Received RealDebrid error: {torrent.RdStatusRaw}, not processing further", torrent);
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@ namespace RdtClient.Service.Services
|
||||||
|
|
||||||
private readonly ITorrentClient _torrentClient;
|
private readonly ITorrentClient _torrentClient;
|
||||||
|
|
||||||
|
public static readonly SemaphoreSlim TorrentResetLock = new(1, 1);
|
||||||
|
|
||||||
public Torrents(ILogger<Torrents> logger,
|
public Torrents(ILogger<Torrents> logger,
|
||||||
TorrentData torrentData,
|
TorrentData torrentData,
|
||||||
Downloads downloads,
|
Downloads downloads,
|
||||||
|
|
@ -219,6 +221,8 @@ namespace RdtClient.Service.Services
|
||||||
|
|
||||||
Log($"Deleting", torrent);
|
Log($"Deleting", torrent);
|
||||||
|
|
||||||
|
await UpdateComplete(torrentId, DateTimeOffset.UtcNow);
|
||||||
|
|
||||||
foreach (var download in torrent.Downloads)
|
foreach (var download in torrent.Downloads)
|
||||||
{
|
{
|
||||||
while (TorrentRunner.ActiveDownloadClients.TryGetValue(download.DownloadId, out var downloadClient))
|
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)
|
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);
|
if (torrent == null)
|
||||||
|
|
||||||
foreach (var download in torrent.Downloads)
|
|
||||||
{
|
|
||||||
while (TorrentRunner.ActiveDownloadClients.TryGetValue(download.DownloadId, out var downloadClient))
|
|
||||||
{
|
{
|
||||||
await downloadClient.Cancel();
|
return;
|
||||||
|
|
||||||
await Task.Delay(100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 _downloads.UpdateError(download.DownloadId, null);
|
||||||
|
await _downloads.UpdateCompleted(download.DownloadId, DateTimeOffset.Now);
|
||||||
await Task.Delay(100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
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");
|
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)
|
public async Task RetryDownload(Guid downloadId)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
<TargetFramework>net5.0</TargetFramework>
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<UserSecretsId>94c24cba-f03f-4453-a671-3640b517c573</UserSecretsId>
|
<UserSecretsId>94c24cba-f03f-4453-a671-3640b517c573</UserSecretsId>
|
||||||
<Version>1.9.3</Version>
|
<Version>1.9.4</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue