Improved stop handling during backend retries
This commit is contained in:
@@ -424,11 +424,11 @@ partial class BackendManager
|
||||
|
||||
// Refresh DNS name if we fail to connect in order to prevent issues with incorrect DNS entries
|
||||
var dnsFailure = Library.Utility.ExceptionExtensions.FlattenException(ex)
|
||||
.Any(x =>
|
||||
(x is System.Net.WebException wex && wex.Status == System.Net.WebExceptionStatus.NameResolutionFailure)
|
||||
||
|
||||
(x is System.Net.Sockets.SocketException sockEx && sockEx.SocketErrorCode == System.Net.Sockets.SocketError.HostNotFound)
|
||||
);
|
||||
.Any(x =>
|
||||
(x is System.Net.WebException wex && wex.Status == System.Net.WebExceptionStatus.NameResolutionFailure)
|
||||
||
|
||||
(x is System.Net.Sockets.SocketException sockEx && sockEx.SocketErrorCode == System.Net.Sockets.SocketError.HostNotFound)
|
||||
);
|
||||
if (dnsFailure)
|
||||
{
|
||||
try
|
||||
@@ -459,10 +459,17 @@ partial class BackendManager
|
||||
if (!recovered && retries <= maxRetries && retryDelay.Ticks != 0)
|
||||
{
|
||||
var delay = Library.Utility.Utility.GetRetryDelay(retryDelay, retries, retryWithExponentialBackoff);
|
||||
await Task.Delay(delay, context.TaskReader.ProgressToken).ConfigureAwait(false);
|
||||
using var ct = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, context.TaskReader.ProgressToken, context.TaskReader.TransferToken, context.TaskReader.StopToken);
|
||||
await Task.Delay(delay, ct.Token).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (!await context.TaskReader.ProgressRendevouz())
|
||||
{
|
||||
op.SetCancelled();
|
||||
return;
|
||||
}
|
||||
|
||||
} while (retries <= maxRetries);
|
||||
|
||||
// If we have a last exception, we failed
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
// Copyright (C) 2025, The Duplicati Team
|
||||
// https://duplicati.com, hello@duplicati.com
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// Copyright (C) 2025, The Duplicati Team
|
||||
// https://duplicati.com, hello@duplicati.com
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
@@ -52,6 +52,11 @@ namespace Duplicati.Library.Main.Operation.Common
|
||||
/// <returns><c>true</c> if the transfer should continue, <c>false</c> if it should stop</returns>
|
||||
Task<bool> TransferRendevouz();
|
||||
|
||||
/// <summary>
|
||||
/// A cancellation token that can be used to monitor stop requests
|
||||
/// </summary>
|
||||
CancellationToken StopToken { get; }
|
||||
|
||||
#if DEBUG
|
||||
/// <summary>
|
||||
/// Callback for testing the task control
|
||||
@@ -142,6 +147,11 @@ namespace Duplicati.Library.Main.Operation.Common
|
||||
/// </summary>
|
||||
private readonly CancellationTokenSource m_transferTcs = new();
|
||||
|
||||
/// <summary>
|
||||
/// Cancellation token source that is cancelled if the operation is stopped
|
||||
/// </summary>
|
||||
private readonly CancellationTokenSource m_stopTcs = new CancellationTokenSource();
|
||||
|
||||
/// <summary>
|
||||
/// The control lock instance
|
||||
/// </summary>
|
||||
@@ -167,6 +177,11 @@ namespace Duplicati.Library.Main.Operation.Common
|
||||
/// </summary>
|
||||
public CancellationToken TransferToken => m_transferTcs.Token;
|
||||
|
||||
/// <summary>
|
||||
/// A cancellation token that is cancelled if the operation is stopped
|
||||
/// </summary>
|
||||
public CancellationToken StopToken => m_stopTcs.Token;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Duplicati.Library.Main.Operation.Common.TaskControl"/> class.
|
||||
/// </summary>
|
||||
@@ -269,6 +284,8 @@ namespace Duplicati.Library.Main.Operation.Common
|
||||
m_transfer.SetResult(false);
|
||||
m_transferstate = State.Stopped;
|
||||
}
|
||||
|
||||
m_stopTcs.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,6 +315,8 @@ namespace Duplicati.Library.Main.Operation.Common
|
||||
m_transferstate = State.Terminated;
|
||||
m_transferTcs.Cancel();
|
||||
}
|
||||
|
||||
m_stopTcs.Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user