Add simple retry mechanism for network connection drops.

This commit is contained in:
Roger Far 2021-01-13 11:04:42 -07:00
parent 860ffe95e4
commit 0a8793e4f9
6 changed files with 87 additions and 36 deletions

View file

@ -54,7 +54,10 @@ export class TorrentRowComponent implements OnInit {
}
public canDownload(): boolean {
return this.torrent.rdStatus === RealDebridStatus.Finished && this.torrent.downloads.length === 0;
return (
(this.torrent.rdStatus === RealDebridStatus.Finished && this.torrent.downloads.length === 0) ||
(this.torrent.downloads.length > 0 && this.torrent.downloads.any((m) => m.error != null))
);
}
public canUnpack(): boolean {

View file

@ -9,23 +9,19 @@ export class TorrentStatusPipe implements PipeTransform {
constructor(private pipe: FileSizePipe) {}
transform(torrent: Torrent): string {
if (torrent.completed) {
return 'Finished';
}
if (torrent.downloads.length > 0) {
const allFinished = torrent.downloads.all((m) => m.completed != null);
if (allFinished) {
return 'Finished';
}
const errors = torrent.downloads.where((m) => m.error != null);
if (errors.length > 0) {
return 'Error';
}
const allFinished = torrent.downloads.all((m) => m.completed != null);
if (allFinished) {
return 'Finished';
}
const downloading = torrent.downloads.where((m) => m.downloadStarted && !m.downloadFinished);
if (downloading.length > 0) {
@ -80,6 +76,10 @@ export class TorrentStatusPipe implements PipeTransform {
}
}
if (torrent.completed) {
return 'Finished';
}
switch (torrent.rdStatus) {
case RealDebridStatus.Downloading:
const speed = this.pipe.transform(torrent.rdSpeed, 'filesize');

View file

@ -89,6 +89,11 @@ namespace RdtClient.Data.Data
var dbDownload = await _dataContext.Downloads
.FirstOrDefaultAsync(m => m.DownloadId == downloadId);
if (dbDownload == null)
{
return;
}
dbDownload.DownloadFinished = dateTime;
await _dataContext.SaveChangesAsync();

View file

@ -84,6 +84,7 @@ namespace RdtClient.Service.Services
// Determine the file size
var webRequest = WebRequest.Create(uri);
webRequest.Method = "HEAD";
webRequest.Timeout = 5000;
Int64 responseLength;
using (var webResponse = await webRequest.GetResponseAsync())
@ -91,36 +92,67 @@ namespace RdtClient.Service.Services
responseLength = Int64.Parse(webResponse.Headers.Get("Content-Length"));
}
var request = WebRequest.Create(uri);
using var response = await request.GetResponseAsync();
var timeout = DateTimeOffset.UtcNow.AddHours(1);
await using var stream = response.GetResponseStream();
await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Write);
var buffer = new Byte[4096];
while (fileStream.Length < response.ContentLength)
while (timeout > DateTimeOffset.UtcNow)
{
var read = await stream.ReadAsync(buffer, 0, buffer.Length);
if (read > 0)
try
{
fileStream.Write(buffer, 0, read);
var request = WebRequest.Create(uri);
using var response = await request.GetResponseAsync();
BytesDone = fileStream.Length;
BytesTotal = responseLength;
await using var stream = response.GetResponseStream();
if (DateTime.UtcNow > _nextUpdate)
if (stream == null)
{
Speed = fileStream.Length - _bytesLastUpdate;
_nextUpdate = DateTime.UtcNow.AddSeconds(1);
_bytesLastUpdate = fileStream.Length;
throw new IOException("No stream");
}
}
else
{
await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Write);
var buffer = new Byte[4096];
while (fileStream.Length < response.ContentLength)
{
var read = await stream.ReadAsync(buffer, 0, buffer.Length);
if (read > 0)
{
fileStream.Write(buffer, 0, read);
BytesDone = fileStream.Length;
BytesTotal = responseLength;
if (DateTime.UtcNow > _nextUpdate)
{
Speed = fileStream.Length - _bytesLastUpdate;
_nextUpdate = DateTime.UtcNow.AddSeconds(1);
_bytesLastUpdate = fileStream.Length;
timeout = DateTimeOffset.UtcNow.AddHours(1);
}
}
else
{
break;
}
}
break;
}
catch (IOException)
{
await Task.Delay(1000);
}
catch (WebException)
{
await Task.Delay(1000);
}
}
if (timeout <= DateTimeOffset.UtcNow)
{
throw new Exception($"Download timed out");
}
Speed = 0;

View file

@ -134,7 +134,7 @@ namespace RdtClient.Service.Services
// Check if there are any downloads that are queued and can be started.
var queuedDownloads = torrents.SelectMany(m => m.Downloads)
.Where(m => m.DownloadQueued != null && m.DownloadStarted == null)
.Where(m => m.Completed == null && m.DownloadQueued != null && m.DownloadStarted == null)
.OrderBy(m => m.DownloadQueued);
foreach (var download in queuedDownloads)
@ -144,7 +144,7 @@ namespace RdtClient.Service.Services
// Check if there are any unpacks that are queued and can be started.
var queuedUnpacks = torrents.SelectMany(m => m.Downloads)
.Where(m => m.UnpackingQueued != null && m.UnpackingStarted == null)
.Where(m => m.Completed == null && m.UnpackingQueued != null && m.UnpackingStarted == null)
.OrderBy(m => m.DownloadQueued);
foreach (var download in queuedUnpacks)
@ -197,7 +197,8 @@ namespace RdtClient.Service.Services
// If the torrent has any files that need starting to be downloaded, download them.
var downloadsPending = torrent.Downloads
.Where(m => m.DownloadStarted == null &&
.Where(m => m.Completed == null &&
m.DownloadStarted == null &&
m.DownloadFinished == null)
.ToList();
@ -216,7 +217,8 @@ namespace RdtClient.Service.Services
{
// If all files are finished downloading, move to the unpacking step.
var unpackingPending = torrent.Downloads
.Where(m => m.DownloadFinished != null &&
.Where(m => m.Completed == null &&
m.DownloadFinished != null &&
m.UnpackingStarted == null &&
m.UnpackingFinished == null)
.ToList();

View file

@ -214,6 +214,15 @@ namespace RdtClient.Service.Services
var downloadPath = await DownloadPath(download.Torrent);
download.DownloadFinished = null;
await _downloads.UpdateDownloadStarted(download.DownloadId, null);
download.Completed = null;
await _downloads.UpdateCompleted(download.DownloadId, null);
download.Error = null;
await _downloads.UpdateError(download.DownloadId, null);
// Check if we have reached the download limit, if so queue the download, but don't start it.
if (TorrentRunner.ActiveDownloadClients.Count >= settingDownloadLimit)
{