* Rewrite the backend manager. This creates a new more logic backend manager that handles all backend operations. For each top-level operation, there is now a single backend manager instance that is passed to sub-commands. The internals of the backend manager are now rewritten to use async logic instead of threading. The design uses a single task runner that dispatches operations and honors concurrent settings and limits from one place. The logic for each operation has been moved into a separate files/classes to make it easier to understand each operation. This fixes #5804 * Fixed a few issues with not awaiting tasks * Fixed not creating empty databases * Fixed an issue with hashes not being recorded on download * Reworked the download logic to avoid attempting to decrypt the file if it has been modified. * Review fixes * Renamed db collector to better reflect the purpose. * Review fixes
113 lines
5.0 KiB
C#
113 lines
5.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Duplicati.Library.Interface;
|
|
using Duplicati.Library.Main.Database;
|
|
using Duplicati.Library.Main.Volumes;
|
|
using Duplicati.Library.Utility;
|
|
using IFileEntry = Duplicati.Library.Interface.IFileEntry;
|
|
|
|
#nullable enable
|
|
|
|
namespace Duplicati.Library.Main;
|
|
|
|
/// <summary>
|
|
/// Interface for the backend manager
|
|
/// </summary>
|
|
internal interface IBackendManager : IDisposable
|
|
{
|
|
/// <summary>
|
|
/// Uploads a block volume to the backend, including an optional index volume
|
|
/// </summary>
|
|
/// <param name="blockVolume">The block volume to upload</param>
|
|
/// <param name="indexVolume">The index volume to upload, if any</param>
|
|
/// <param name="indexVolumeFinished">The action to call when the index volume is finished</param>
|
|
/// <param name="waitForComplete">Whether to wait for the upload to complete</param>
|
|
/// <param name="cancelToken">The cancellation token</param>
|
|
/// <returns>An awaitable task</returns>
|
|
Task PutAsync(VolumeWriterBase blockVolume, IndexVolumeWriter? indexVolume, Action? indexVolumeFinished, bool waitForComplete, CancellationToken cancelToken);
|
|
|
|
/// <summary>
|
|
/// Uploads a file to the backend without encryption
|
|
/// </summary>
|
|
/// <param name="remotename">The name of the file to upload to</param>
|
|
/// <param name="tempFile">The file to upload</param>
|
|
/// <param name="cancelToken">The cancellation token</param>
|
|
/// <returns>An awaitable task</returns>
|
|
Task PutVerificationFileAsync(string remotename, TempFile tempFile, CancellationToken cancelToken);
|
|
|
|
/// <summary>
|
|
/// Waits for the backend queue to be empty and flushes any pending messages to the database
|
|
/// </summary>
|
|
/// <param name="database">The database to write pending messages to</param>
|
|
/// <param name="transaction">The transaction to use, if any</param>
|
|
/// <param name="cancellationToken">The cancellation token</param>
|
|
/// <returns>An awaitable task</returns>
|
|
Task WaitForEmptyAsync(LocalDatabase database, IDbTransaction? transaction, CancellationToken cancellationToken);
|
|
|
|
/// <summary>
|
|
/// Lists the files on the backend
|
|
/// </summary>
|
|
/// <param name="cancelToken">The cancellation token</param>
|
|
/// <returns>An enumerable of file entries</returns>
|
|
Task<IEnumerable<IFileEntry>> ListAsync(CancellationToken cancelToken);
|
|
|
|
/// <summary>
|
|
/// Deletes a file on the backend
|
|
/// </summary>
|
|
/// <param name="remotename">The name of the file to delete</param>
|
|
/// <param name="size">The size of the file to delete, or -1 if not known</param>
|
|
/// <param name="waitForComplete">Whether to wait for the delete to complete</param>
|
|
/// <param name="cancelToken">The cancellation token</param>
|
|
/// <returns>An awaitable task</returns>
|
|
Task DeleteAsync(string remotename, long size, bool waitForComplete, CancellationToken cancelToken);
|
|
|
|
/// <summary>
|
|
/// Gets the quota information for the backend
|
|
/// </summary>
|
|
/// <param name="cancelToken">The cancellation token</param>
|
|
/// <returns>The quota information, or null if not available or disabled</returns>
|
|
Task<IQuotaInfo?> GetQuotaInfoAsync(CancellationToken cancelToken);
|
|
|
|
/// <summary>
|
|
/// Gets a file with the hash and size
|
|
/// </summary>
|
|
/// <param name="remotename">The name of the file to get</param>
|
|
/// <param name="hash">The hash of the file to get, or <c>null</c> if not known</param>
|
|
/// <param name="size">The size of the file to get, or -1 if not known</param>
|
|
/// <param name="cancelToken">The cancellation token</param>
|
|
/// <returns>The file, hash, and size</returns>
|
|
Task<(TempFile File, string Hash, long Size)> GetWithInfoAsync(string remotename, string hash, long size, CancellationToken cancelToken);
|
|
|
|
/// <summary>
|
|
/// Gets a file from the backend
|
|
/// </summary>
|
|
/// <param name="remotename">The name of the file to get</param>
|
|
/// <param name="hash">The hash of the file to get, or <c>null</c> if not known</param>
|
|
/// <param name="size">The size of the file to get, or -1 if not known</param>
|
|
/// <param name="cancelToken">The cancellation token</param>
|
|
/// <returns></returns>
|
|
Task<TempFile> GetAsync(string remotename, string hash, long size, CancellationToken cancelToken);
|
|
|
|
/// <summary>
|
|
/// Performs a download of the files specified, with pre-fetch to overlap the download and processing
|
|
/// </summary>
|
|
/// <param name="volumes">The volumes to download</param>
|
|
/// <param name="cancelToken">The cancellation token</param>
|
|
/// <returns>The downloaded files, hash, size, and name</returns>
|
|
IAsyncEnumerable<(TempFile File, string Hash, long Size, string Name)> GetFilesOverlappedAsync(IEnumerable<IRemoteVolume> volumes, CancellationToken cancelToken);
|
|
|
|
/// <summary>
|
|
/// Gets the size of the last read operation
|
|
/// </summary>
|
|
long LastReadSize { get; }
|
|
|
|
/// <summary>
|
|
/// Gets the size of the last write operation
|
|
/// </summary>
|
|
long LastWriteSize { get; }
|
|
|
|
}
|