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 {
|
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 {
|
public canUnpack(): boolean {
|
||||||
|
|
|
||||||
|
|
@ -9,23 +9,19 @@ export class TorrentStatusPipe implements PipeTransform {
|
||||||
constructor(private pipe: FileSizePipe) {}
|
constructor(private pipe: FileSizePipe) {}
|
||||||
|
|
||||||
transform(torrent: Torrent): string {
|
transform(torrent: Torrent): string {
|
||||||
if (torrent.completed) {
|
|
||||||
return 'Finished';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (torrent.downloads.length > 0) {
|
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);
|
const errors = torrent.downloads.where((m) => m.error != null);
|
||||||
|
|
||||||
if (errors.length > 0) {
|
if (errors.length > 0) {
|
||||||
return 'Error';
|
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);
|
const downloading = torrent.downloads.where((m) => m.downloadStarted && !m.downloadFinished);
|
||||||
|
|
||||||
if (downloading.length > 0) {
|
if (downloading.length > 0) {
|
||||||
|
|
@ -80,6 +76,10 @@ export class TorrentStatusPipe implements PipeTransform {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (torrent.completed) {
|
||||||
|
return 'Finished';
|
||||||
|
}
|
||||||
|
|
||||||
switch (torrent.rdStatus) {
|
switch (torrent.rdStatus) {
|
||||||
case RealDebridStatus.Downloading:
|
case RealDebridStatus.Downloading:
|
||||||
const speed = this.pipe.transform(torrent.rdSpeed, 'filesize');
|
const speed = this.pipe.transform(torrent.rdSpeed, 'filesize');
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,11 @@ namespace RdtClient.Data.Data
|
||||||
var dbDownload = await _dataContext.Downloads
|
var dbDownload = await _dataContext.Downloads
|
||||||
.FirstOrDefaultAsync(m => m.DownloadId == downloadId);
|
.FirstOrDefaultAsync(m => m.DownloadId == downloadId);
|
||||||
|
|
||||||
|
if (dbDownload == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
dbDownload.DownloadFinished = dateTime;
|
dbDownload.DownloadFinished = dateTime;
|
||||||
|
|
||||||
await _dataContext.SaveChangesAsync();
|
await _dataContext.SaveChangesAsync();
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,7 @@ namespace RdtClient.Service.Services
|
||||||
// Determine the file size
|
// Determine the file size
|
||||||
var webRequest = WebRequest.Create(uri);
|
var webRequest = WebRequest.Create(uri);
|
||||||
webRequest.Method = "HEAD";
|
webRequest.Method = "HEAD";
|
||||||
|
webRequest.Timeout = 5000;
|
||||||
Int64 responseLength;
|
Int64 responseLength;
|
||||||
|
|
||||||
using (var webResponse = await webRequest.GetResponseAsync())
|
using (var webResponse = await webRequest.GetResponseAsync())
|
||||||
|
|
@ -91,36 +92,67 @@ namespace RdtClient.Service.Services
|
||||||
responseLength = Int64.Parse(webResponse.Headers.Get("Content-Length"));
|
responseLength = Int64.Parse(webResponse.Headers.Get("Content-Length"));
|
||||||
}
|
}
|
||||||
|
|
||||||
var request = WebRequest.Create(uri);
|
var timeout = DateTimeOffset.UtcNow.AddHours(1);
|
||||||
using var response = await request.GetResponseAsync();
|
|
||||||
|
|
||||||
await using var stream = response.GetResponseStream();
|
while (timeout > DateTimeOffset.UtcNow)
|
||||||
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);
|
try
|
||||||
|
|
||||||
if (read > 0)
|
|
||||||
{
|
{
|
||||||
fileStream.Write(buffer, 0, read);
|
var request = WebRequest.Create(uri);
|
||||||
|
using var response = await request.GetResponseAsync();
|
||||||
|
|
||||||
BytesDone = fileStream.Length;
|
await using var stream = response.GetResponseStream();
|
||||||
BytesTotal = responseLength;
|
|
||||||
|
|
||||||
if (DateTime.UtcNow > _nextUpdate)
|
if (stream == null)
|
||||||
{
|
{
|
||||||
Speed = fileStream.Length - _bytesLastUpdate;
|
throw new IOException("No stream");
|
||||||
|
|
||||||
_nextUpdate = DateTime.UtcNow.AddSeconds(1);
|
|
||||||
_bytesLastUpdate = fileStream.Length;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
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;
|
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;
|
Speed = 0;
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ namespace RdtClient.Service.Services
|
||||||
|
|
||||||
// Check if there are any downloads that are queued and can be started.
|
// Check if there are any downloads that are queued and can be started.
|
||||||
var queuedDownloads = torrents.SelectMany(m => m.Downloads)
|
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);
|
.OrderBy(m => m.DownloadQueued);
|
||||||
|
|
||||||
foreach (var download in queuedDownloads)
|
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.
|
// Check if there are any unpacks that are queued and can be started.
|
||||||
var queuedUnpacks = torrents.SelectMany(m => m.Downloads)
|
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);
|
.OrderBy(m => m.DownloadQueued);
|
||||||
|
|
||||||
foreach (var download in queuedUnpacks)
|
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.
|
// If the torrent has any files that need starting to be downloaded, download them.
|
||||||
var downloadsPending = torrent.Downloads
|
var downloadsPending = torrent.Downloads
|
||||||
.Where(m => m.DownloadStarted == null &&
|
.Where(m => m.Completed == null &&
|
||||||
|
m.DownloadStarted == null &&
|
||||||
m.DownloadFinished == null)
|
m.DownloadFinished == null)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
|
@ -216,7 +217,8 @@ namespace RdtClient.Service.Services
|
||||||
{
|
{
|
||||||
// If all files are finished downloading, move to the unpacking step.
|
// If all files are finished downloading, move to the unpacking step.
|
||||||
var unpackingPending = torrent.Downloads
|
var unpackingPending = torrent.Downloads
|
||||||
.Where(m => m.DownloadFinished != null &&
|
.Where(m => m.Completed == null &&
|
||||||
|
m.DownloadFinished != null &&
|
||||||
m.UnpackingStarted == null &&
|
m.UnpackingStarted == null &&
|
||||||
m.UnpackingFinished == null)
|
m.UnpackingFinished == null)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
|
||||||
|
|
@ -214,6 +214,15 @@ namespace RdtClient.Service.Services
|
||||||
|
|
||||||
var downloadPath = await DownloadPath(download.Torrent);
|
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.
|
// Check if we have reached the download limit, if so queue the download, but don't start it.
|
||||||
if (TorrentRunner.ActiveDownloadClients.Count >= settingDownloadLimit)
|
if (TorrentRunner.ActiveDownloadClients.Count >= settingDownloadLimit)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue