diff --git a/server/RdtClient.Data/Data/TorrentData.cs b/server/RdtClient.Data/Data/TorrentData.cs
index 043a95a..4880a6e 100644
--- a/server/RdtClient.Data/Data/TorrentData.cs
+++ b/server/RdtClient.Data/Data/TorrentData.cs
@@ -196,6 +196,22 @@ namespace RdtClient.Data.Data
await VoidCache();
}
+ public async Task UpdateRetryCount(Guid torrentId, Int32 retryCount)
+ {
+ var dbTorrent = await _dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrentId);
+
+ if (dbTorrent == null)
+ {
+ return;
+ }
+
+ dbTorrent.RetryCount = retryCount;
+
+ await _dataContext.SaveChangesAsync();
+
+ await VoidCache();
+ }
+
public async Task Delete(Guid torrentId)
{
var dbTorrent = await _dataContext.Torrents.FirstOrDefaultAsync(m => m.TorrentId == torrentId);
diff --git a/server/RdtClient.Data/Migrations/20211011193848_Torrent_Add_RetryCount.Designer.cs b/server/RdtClient.Data/Migrations/20211011193848_Torrent_Add_RetryCount.Designer.cs
new file mode 100644
index 0000000..05d356b
--- /dev/null
+++ b/server/RdtClient.Data/Migrations/20211011193848_Torrent_Add_RetryCount.Designer.cs
@@ -0,0 +1,439 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using RdtClient.Data.Data;
+
+namespace RdtClient.Data.Migrations
+{
+ [DbContext(typeof(DataContext))]
+ [Migration("20211011193848_Torrent_Add_RetryCount")]
+ partial class Torrent_Add_RetryCount
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "5.0.10");
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("TEXT");
+
+ b.Property("Name")
+ .HasMaxLength(256)
+ .HasColumnType("TEXT");
+
+ b.Property("NormalizedName")
+ .HasMaxLength(256)
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName")
+ .IsUnique()
+ .HasDatabaseName("RoleNameIndex");
+
+ b.ToTable("AspNetRoles");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("ClaimType")
+ .HasColumnType("TEXT");
+
+ b.Property("ClaimValue")
+ .HasColumnType("TEXT");
+
+ b.Property("RoleId")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetRoleClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT");
+
+ b.Property("AccessFailedCount")
+ .HasColumnType("INTEGER");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("TEXT");
+
+ b.Property("Email")
+ .HasMaxLength(256)
+ .HasColumnType("TEXT");
+
+ b.Property("EmailConfirmed")
+ .HasColumnType("INTEGER");
+
+ b.Property("LockoutEnabled")
+ .HasColumnType("INTEGER");
+
+ b.Property("LockoutEnd")
+ .HasColumnType("TEXT");
+
+ b.Property("NormalizedEmail")
+ .HasMaxLength(256)
+ .HasColumnType("TEXT");
+
+ b.Property("NormalizedUserName")
+ .HasMaxLength(256)
+ .HasColumnType("TEXT");
+
+ b.Property("PasswordHash")
+ .HasColumnType("TEXT");
+
+ b.Property("PhoneNumber")
+ .HasColumnType("TEXT");
+
+ b.Property("PhoneNumberConfirmed")
+ .HasColumnType("INTEGER");
+
+ b.Property("SecurityStamp")
+ .HasColumnType("TEXT");
+
+ b.Property("TwoFactorEnabled")
+ .HasColumnType("INTEGER");
+
+ b.Property("UserName")
+ .HasMaxLength(256)
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedEmail")
+ .HasDatabaseName("EmailIndex");
+
+ b.HasIndex("NormalizedUserName")
+ .IsUnique()
+ .HasDatabaseName("UserNameIndex");
+
+ b.ToTable("AspNetUsers");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("ClaimType")
+ .HasColumnType("TEXT");
+
+ b.Property("ClaimValue")
+ .HasColumnType("TEXT");
+
+ b.Property("UserId")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
+ {
+ b.Property("LoginProvider")
+ .HasColumnType("TEXT");
+
+ b.Property("ProviderKey")
+ .HasColumnType("TEXT");
+
+ b.Property("ProviderDisplayName")
+ .HasColumnType("TEXT");
+
+ b.Property("UserId")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.HasKey("LoginProvider", "ProviderKey");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserLogins");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.Property("RoleId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetUserRoles");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.Property("LoginProvider")
+ .HasColumnType("TEXT");
+
+ b.Property("Name")
+ .HasColumnType("TEXT");
+
+ b.Property("Value")
+ .HasColumnType("TEXT");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("AspNetUserTokens");
+ });
+
+ modelBuilder.Entity("RdtClient.Data.Models.Data.Download", b =>
+ {
+ b.Property("DownloadId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT");
+
+ b.Property("Added")
+ .HasColumnType("TEXT");
+
+ b.Property("Completed")
+ .HasColumnType("TEXT");
+
+ b.Property("DownloadFinished")
+ .HasColumnType("TEXT");
+
+ b.Property("DownloadQueued")
+ .HasColumnType("TEXT");
+
+ b.Property("DownloadStarted")
+ .HasColumnType("TEXT");
+
+ b.Property("Error")
+ .HasColumnType("TEXT");
+
+ b.Property("Link")
+ .HasColumnType("TEXT");
+
+ b.Property("Path")
+ .HasColumnType("TEXT");
+
+ b.Property("RemoteId")
+ .HasColumnType("TEXT");
+
+ b.Property("RetryCount")
+ .HasColumnType("INTEGER");
+
+ b.Property("TorrentId")
+ .HasColumnType("TEXT");
+
+ b.Property("UnpackingFinished")
+ .HasColumnType("TEXT");
+
+ b.Property("UnpackingQueued")
+ .HasColumnType("TEXT");
+
+ b.Property("UnpackingStarted")
+ .HasColumnType("TEXT");
+
+ b.HasKey("DownloadId");
+
+ b.HasIndex("TorrentId");
+
+ b.ToTable("Downloads");
+ });
+
+ modelBuilder.Entity("RdtClient.Data.Models.Data.Setting", b =>
+ {
+ b.Property("SettingId")
+ .HasColumnType("TEXT");
+
+ b.Property("Type")
+ .HasColumnType("TEXT");
+
+ b.Property("Value")
+ .HasColumnType("TEXT");
+
+ b.HasKey("SettingId");
+
+ b.ToTable("Settings");
+ });
+
+ modelBuilder.Entity("RdtClient.Data.Models.Data.Torrent", b =>
+ {
+ b.Property("TorrentId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT");
+
+ b.Property("Added")
+ .HasColumnType("TEXT");
+
+ b.Property("Category")
+ .HasColumnType("TEXT");
+
+ b.Property("Completed")
+ .HasColumnType("TEXT");
+
+ b.Property("DownloadAction")
+ .HasColumnType("INTEGER");
+
+ b.Property("DownloadManualFiles")
+ .HasColumnType("TEXT");
+
+ b.Property("DownloadMinSize")
+ .HasColumnType("INTEGER");
+
+ b.Property("FileOrMagnet")
+ .HasColumnType("TEXT");
+
+ b.Property("FilesSelected")
+ .HasColumnType("TEXT");
+
+ b.Property("FinishedAction")
+ .HasColumnType("INTEGER");
+
+ b.Property("Hash")
+ .HasColumnType("TEXT");
+
+ b.Property("IsFile")
+ .HasColumnType("INTEGER");
+
+ b.Property("RdAdded")
+ .HasColumnType("TEXT");
+
+ b.Property("RdEnded")
+ .HasColumnType("TEXT");
+
+ b.Property("RdFiles")
+ .HasColumnType("TEXT");
+
+ b.Property("RdHost")
+ .HasColumnType("TEXT");
+
+ b.Property("RdId")
+ .HasColumnType("TEXT");
+
+ b.Property("RdName")
+ .HasColumnType("TEXT");
+
+ b.Property("RdProgress")
+ .HasColumnType("INTEGER");
+
+ b.Property("RdSeeders")
+ .HasColumnType("INTEGER");
+
+ b.Property("RdSize")
+ .HasColumnType("INTEGER");
+
+ b.Property("RdSpeed")
+ .HasColumnType("INTEGER");
+
+ b.Property("RdSplit")
+ .HasColumnType("INTEGER");
+
+ b.Property("RdStatus")
+ .HasColumnType("INTEGER");
+
+ b.Property("RdStatusRaw")
+ .HasColumnType("TEXT");
+
+ b.Property("RetryCount")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("TorrentId");
+
+ b.ToTable("Torrents");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+
+ b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("RdtClient.Data.Models.Data.Download", b =>
+ {
+ b.HasOne("RdtClient.Data.Models.Data.Torrent", "Torrent")
+ .WithMany("Downloads")
+ .HasForeignKey("TorrentId")
+ .OnDelete(DeleteBehavior.Restrict)
+ .IsRequired();
+
+ b.Navigation("Torrent");
+ });
+
+ modelBuilder.Entity("RdtClient.Data.Models.Data.Torrent", b =>
+ {
+ b.Navigation("Downloads");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/server/RdtClient.Data/Migrations/20211011193848_Torrent_Add_RetryCount.cs b/server/RdtClient.Data/Migrations/20211011193848_Torrent_Add_RetryCount.cs
new file mode 100644
index 0000000..bbaae0e
--- /dev/null
+++ b/server/RdtClient.Data/Migrations/20211011193848_Torrent_Add_RetryCount.cs
@@ -0,0 +1,24 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace RdtClient.Data.Migrations
+{
+ public partial class Torrent_Add_RetryCount : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AddColumn(
+ name: "RetryCount",
+ table: "Torrents",
+ type: "INTEGER",
+ nullable: false,
+ defaultValue: 0);
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropColumn(
+ name: "RetryCount",
+ table: "Torrents");
+ }
+ }
+}
diff --git a/server/RdtClient.Data/Migrations/DataContextModelSnapshot.cs b/server/RdtClient.Data/Migrations/DataContextModelSnapshot.cs
index f4cf51b..bf25f46 100644
--- a/server/RdtClient.Data/Migrations/DataContextModelSnapshot.cs
+++ b/server/RdtClient.Data/Migrations/DataContextModelSnapshot.cs
@@ -357,6 +357,9 @@ namespace RdtClient.Data.Migrations
b.Property("RdStatusRaw")
.HasColumnType("TEXT");
+ b.Property("RetryCount")
+ .HasColumnType("INTEGER");
+
b.HasKey("TorrentId");
b.ToTable("Torrents");
diff --git a/server/RdtClient.Data/Models/Data/Torrent.cs b/server/RdtClient.Data/Models/Data/Torrent.cs
index 2a0466e..6775574 100644
--- a/server/RdtClient.Data/Models/Data/Torrent.cs
+++ b/server/RdtClient.Data/Models/Data/Torrent.cs
@@ -29,6 +29,8 @@ namespace RdtClient.Data.Models.Data
public String FileOrMagnet { get; set; }
public Boolean IsFile { get; set; }
+ public Int32 RetryCount { get; set; }
+
[InverseProperty("Torrent")]
public IList Downloads { get; set; }
diff --git a/server/RdtClient.Service/Services/TorrentRunner.cs b/server/RdtClient.Service/Services/TorrentRunner.cs
index bbfc106..2765d8a 100644
--- a/server/RdtClient.Service/Services/TorrentRunner.cs
+++ b/server/RdtClient.Service/Services/TorrentRunner.cs
@@ -12,7 +12,8 @@ namespace RdtClient.Service.Services
{
public class TorrentRunner
{
- private const Int32 RetryCount = 3;
+ private const Int32 DownloadRetryCount = 3;
+ private const Int32 TorrentRetryCount = 2;
private static DateTime _nextUpdate = DateTime.UtcNow;
@@ -103,13 +104,20 @@ namespace RdtClient.Service.Services
Log.Debug($"Processing active download {downloadId}: error {downloadClient.Error}");
var download = await _downloads.GetById(downloadId);
- if (download.RetryCount < RetryCount)
+ if (download.RetryCount < DownloadRetryCount)
{
- Log.Debug($"Processing active download {downloadId}: error {downloadClient.Error}, retry count {download.RetryCount}/{RetryCount}");
+ Log.Debug($"Processing active download {downloadId}: error {downloadClient.Error}, download retry count {download.RetryCount}/{DownloadRetryCount}, torrent retry count {download.Torrent.RetryCount}/{TorrentRetryCount}, retrying download");
await _downloads.UpdateRetryCount(downloadId, download.RetryCount + 1);
await _torrents.Download(downloadId);
}
+ else if (download.Torrent.RetryCount < TorrentRetryCount)
+ {
+ Log.Debug($"Processing active download {downloadId}: error {downloadClient.Error}, download retry count {download.RetryCount}/{DownloadRetryCount}, torrent retry count {download.Torrent.RetryCount}/{TorrentRetryCount}, retrying torrent");
+
+ await _torrents.UpdateRetryCount(download.TorrentId, download.Torrent.RetryCount + 1);
+ await _torrents.RetryTorrent(download.TorrentId);
+ }
else
{
Log.Debug($"Processing active download {downloadId}: error {downloadClient.Error}, not retrying");
diff --git a/server/RdtClient.Service/Services/Torrents.cs b/server/RdtClient.Service/Services/Torrents.cs
index bd2045b..3bd457b 100644
--- a/server/RdtClient.Service/Services/Torrents.cs
+++ b/server/RdtClient.Service/Services/Torrents.cs
@@ -392,14 +392,14 @@ namespace RdtClient.Service.Services
{
downloadClient.Cancel();
- await Task.Delay(100);
+ await Task.Delay(1000);
}
while (TorrentRunner.ActiveUnpackClients.TryGetValue(download.DownloadId, out var unpackClient))
{
unpackClient.Cancel();
- await Task.Delay(100);
+ await Task.Delay(1000);
}
}
@@ -635,5 +635,10 @@ namespace RdtClient.Service.Services
await _torrentData.UpdateRdData(torrent);
}
}
+
+ public async Task UpdateRetryCount(Guid torrentId, Int32 retryCount)
+ {
+ await _torrentData.UpdateRetryCount(torrentId, retryCount);
+ }
}
}