Add simple retry mechanism for network connection drops.
This commit is contained in:
parent
860ffe95e4
commit
0a8793e4f9
6 changed files with 87 additions and 36 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue