mirror of
https://github.com/duplicati/duplicati.git
synced 2025-11-28 03:20:25 +08:00
This PR adds the option to disable throttle on a backup, so it will ignore throttle settings both from the server and the job. Additionally, a list of backend keys can be provided, where backups will disable throttling. This can be used to set advanced options with a set of backends that should not be throttled. By default, the `file` backend is now exempt from throttling by default. This fixes #2685
145 lines
No EOL
5.2 KiB
C#
145 lines
No EOL
5.2 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Duplicati.Library.Interface;
|
|
using Duplicati.Library.Main.Operation.Common;
|
|
using Duplicati.StreamUtil;
|
|
|
|
namespace Duplicati.Library.Main.Backend;
|
|
|
|
#nullable enable
|
|
|
|
partial class BackendManager
|
|
{
|
|
/// <summary>
|
|
/// Execution context for the backend manager
|
|
/// </summary>
|
|
/// <param name="ProgressHandler">The progress handler</param>
|
|
/// <param name="Statwriter">The stat writer</param>
|
|
/// <param name="Database">The database collector</param>
|
|
/// <param name="UploadThrottleManager">The upload throttle manager</param>
|
|
/// <param name="DownloadThrottleManager">The download throttle manager</param>
|
|
/// <param name="TaskReader">The task reader</param>
|
|
/// <param name="IsThrottleDisabled">Whether throttling is disabled</param>
|
|
/// <param name="Options">The options</param>
|
|
private sealed record ExecuteContext(
|
|
ProgressHandler ProgressHandler,
|
|
IBackendWriter Statwriter,
|
|
DatabaseCollector Database,
|
|
ThrottleManager UploadThrottleManager,
|
|
ThrottleManager DownloadThrottleManager,
|
|
ITaskReader TaskReader,
|
|
bool IsThrottleDisabled,
|
|
Options Options);
|
|
|
|
/// <summary>
|
|
/// A base non-generic pending operation
|
|
/// </summary>
|
|
private abstract class PendingOperationBase
|
|
{
|
|
/// <summary>
|
|
/// The execution context
|
|
/// </summary>
|
|
public ExecuteContext Context { get; }
|
|
/// <summary>
|
|
/// Whether to wait for the operation to complete.
|
|
/// If false, the operation is queued and the task is returned after the operation is queued.
|
|
/// </summary>
|
|
public bool WaitForComplete { get; }
|
|
/// <summary>
|
|
/// The cancellation token
|
|
/// </summary>
|
|
public CancellationToken CancelToken { get; set; }
|
|
/// <summary>
|
|
/// The type of operation the pending operation represents
|
|
/// </summary>
|
|
public abstract BackendActionType Operation { get; }
|
|
/// <summary>
|
|
/// The remote filename, if any
|
|
/// </summary>
|
|
public virtual string RemoteFilename => string.Empty;
|
|
/// <summary>
|
|
/// The remote size, if any
|
|
/// </summary>
|
|
public virtual long Size => -1L;
|
|
|
|
/// <summary>
|
|
/// Sets the operation as cancelled
|
|
/// </summary>
|
|
public abstract void SetCancelled();
|
|
/// <summary>
|
|
/// Sets the operation as failed
|
|
/// </summary>
|
|
/// <param name="ex">The exception</param>
|
|
public abstract void SetFailed(Exception ex);
|
|
|
|
/// <summary>
|
|
/// Creates a new pending operation
|
|
/// </summary>
|
|
/// <param name="context">The execution context</param>
|
|
/// <param name="waitForComplete">Whether to wait for the operation to complete</param>
|
|
/// <param name="cancelToken">The cancellation token</param>
|
|
public PendingOperationBase(ExecuteContext context, bool waitForComplete, CancellationToken cancelToken)
|
|
{
|
|
Context = context;
|
|
WaitForComplete = waitForComplete;
|
|
CancelToken = cancelToken;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The basic queued backend operation
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Creates a new pending operation
|
|
/// </remarks>
|
|
/// <param name="context">The execution context</param>
|
|
/// <param name="waitForComplete">Whether to wait for the operation to complete</param>
|
|
/// <param name="cancelToken">The cancellation token</param>
|
|
private abstract class PendingOperation<TResult>(ExecuteContext context, bool waitForComplete, CancellationToken cancelToken) : PendingOperationBase(context, waitForComplete, cancelToken)
|
|
{
|
|
/// <summary>
|
|
/// A signal for the task completion
|
|
/// </summary>
|
|
private readonly TaskCompletionSource<TResult> taskCompleteSignal = new TaskCompletionSource<TResult>(TaskCreationOptions.RunContinuationsAsynchronously);
|
|
/// <summary>
|
|
/// The task that is completed when the operation is done
|
|
/// </summary>
|
|
public Task<TResult> GetResult() => taskCompleteSignal.Task;
|
|
|
|
/// <summary>
|
|
/// Sets the operation as complete
|
|
/// </summary>
|
|
public void SetComplete(TResult result)
|
|
{
|
|
taskCompleteSignal.TrySetResult(result);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the operation as failed
|
|
/// </summary>
|
|
/// <param name="ex">The exception</param>
|
|
public override void SetFailed(Exception ex)
|
|
{
|
|
taskCompleteSignal.TrySetException(ex);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the operation as cancelled
|
|
/// </summary>
|
|
public override void SetCancelled()
|
|
{
|
|
taskCompleteSignal.TrySetCanceled();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Executes the operation
|
|
/// </summary>
|
|
/// <param name="backend">The backend to execute the operation on</param>
|
|
/// <param name="cancelToken">The cancellation token</param>
|
|
/// <returns>An awaitable task</returns>
|
|
public abstract Task<TResult> ExecuteAsync(IBackend backend, CancellationToken cancelToken);
|
|
}
|
|
|
|
} |