Merge branch 'master' into feature/add-sqlite-cache-value

This commit is contained in:
Kenneth Skovhede
2025-04-23 16:34:55 +02:00
committed by GitHub
10 changed files with 35 additions and 40 deletions
+1 -1
View File
@@ -37,7 +37,7 @@ var target_extensions = new[] {
// ".css"
}.ToHashSet(StringComparer.OrdinalIgnoreCase);
File.WriteAllText(Path.Combine(startpath, "LICENSE.txt"), Fragments.GetLicenseTextWithPrefixedLines(string.Empty));
File.WriteAllText(Path.Combine(startpath, "LICENSE"), Fragments.GetLicenseTextWithPrefixedLines(string.Empty));
var candidates = Directory.EnumerateFiles(startpath, "*", SearchOption.AllDirectories)
.Where(x => target_extensions.Contains(Path.GetExtension(x) ?? string.Empty));
@@ -36,15 +36,6 @@ internal partial class BackendManager : IBackendManager
/// </summary>
private readonly Task queueRunner;
/// <summary>
/// The last file read size
/// </summary>
public long LastReadSize { get; private set; }
/// <summary>
/// The last file write size
/// </summary>
public long LastWriteSize { get; private set; }
/// <summary>
/// The execution context
/// </summary>
@@ -171,8 +162,7 @@ internal partial class BackendManager : IBackendManager
Decrypt = true
};
await QueueTask(op).ConfigureAwait(false);
(var file, var _, var downloadSize) = await op.GetResult().ConfigureAwait(false);
LastReadSize = downloadSize;
(var file, var _, var _) = await op.GetResult().ConfigureAwait(false);
return file;
}
@@ -192,8 +182,7 @@ internal partial class BackendManager : IBackendManager
Decrypt = false
};
await QueueTask(op).ConfigureAwait(false);
(var file, var _, var downloadSize) = await op.GetResult().ConfigureAwait(false);
LastReadSize = downloadSize;
(var file, var _, var _) = await op.GetResult().ConfigureAwait(false);
return file;
}
@@ -226,7 +215,6 @@ internal partial class BackendManager : IBackendManager
};
await QueueTask(op).ConfigureAwait(false);
(var file, var downloadHash, var downloadSize) = await op.GetResult().ConfigureAwait(false);
LastReadSize = downloadSize;
return (file, downloadHash, downloadSize);
}
@@ -660,6 +660,15 @@ SELECT ""BlocklistHash"".""BlocksetID"" FROM ""BlocklistHash"" WHERE ""Blocklist
base.Dispose();
}
public long GetLastWrittenDBlockVolumeSize(IDbTransaction? transaction)
{
using (var cmd = m_connection.CreateCommand(transaction))
return cmd.SetCommandAndParameters(@"SELECT ""Size"" FROM ""RemoteVolume"" WHERE ""State"" = @State AND ""Type"" = @Type ORDER BY ""ID"" DESC LIMIT 1")
.SetParameterValue("@State", RemoteVolumeState.Uploaded.ToString())
.SetParameterValue("@Type", RemoteVolumeType.Blocks.ToString())
.ExecuteScalarInt64(-1);
}
private long GetPreviousFilesetID(IDbCommand cmd)
{
return GetPreviousFilesetID(cmd, OperationTimestamp, m_filesetId, cmd.Transaction);
@@ -206,17 +206,17 @@ namespace Duplicati.Library.Main.Database
return Library.Utility.Utility.EPOCH.AddSeconds(seconds);
}
public void UpdateRemoteVolume(string name, RemoteVolumeState state, long size, string hash, IDbTransaction? transaction = null)
public void UpdateRemoteVolume(string name, RemoteVolumeState state, long size, string? hash, IDbTransaction? transaction = null)
{
UpdateRemoteVolume(name, state, size, hash, false, transaction);
}
public void UpdateRemoteVolume(string name, RemoteVolumeState state, long size, string hash, bool suppressCleanup, IDbTransaction? transaction = null)
public void UpdateRemoteVolume(string name, RemoteVolumeState state, long size, string? hash, bool suppressCleanup, IDbTransaction? transaction = null)
{
UpdateRemoteVolume(name, state, size, hash, suppressCleanup, new TimeSpan(0), transaction);
}
public void UpdateRemoteVolume(string name, RemoteVolumeState state, long size, string hash, bool suppressCleanup, TimeSpan deleteGraceTime, IDbTransaction? transaction = null)
public void UpdateRemoteVolume(string name, RemoteVolumeState state, long size, string? hash, bool suppressCleanup, TimeSpan deleteGraceTime, IDbTransaction? transaction = null)
{
m_updateremotevolumeCommand.Transaction = transaction;
var c = m_updateremotevolumeCommand.SetParameterValue("@OperationID", m_operationid)
@@ -391,7 +391,7 @@ namespace Duplicati.Library.Main.Database
/// <param name="operation">The operation performed</param>
/// <param name="path">The path involved</param>
/// <param name="data">Any data relating to the operation</param>
public void LogRemoteOperation(string operation, string path, string data, IDbTransaction transaction)
public void LogRemoteOperation(string operation, string path, string? data, IDbTransaction? transaction)
{
m_insertremotelogCommand
.SetParameterValue("@OperationID", m_operationid)
@@ -1434,7 +1434,7 @@ AND oldVersion.FilesetID = (SELECT ID FROM Fileset WHERE ID != @FilesetId ORDER
}
}
public void RenameRemoteFile(string oldname, string newname, IDbTransaction transaction)
public void RenameRemoteFile(string oldname, string newname, IDbTransaction? transaction)
{
using (var tr = new TemporaryTransactionWrapper(m_connection, transaction))
using (var cmd = m_connection.CreateCommand(tr.Parent))
-10
View File
@@ -126,16 +126,6 @@ internal interface IBackendManager : IDisposable
/// <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; }
/// <summary>
/// Flushes the database messages to the database
/// </summary>
@@ -595,7 +595,7 @@ namespace Duplicati.Library.Main.Operation
return new AggregateException(ex.First().Message, ex);
}
private static async Task<long> FlushBackend(Backup.BackupDatabase database, BackupResults result, IBackendManager backendManager)
private static async Task FlushBackend(Backup.BackupDatabase database, BackupResults result, IBackendManager backendManager)
{
// Wait for upload completion
result.OperationProgressUpdater.UpdatePhase(OperationPhase.Backup_WaitForUpload);
@@ -605,14 +605,10 @@ namespace Duplicati.Library.Main.Operation
await database.FlushBackendMessagesAndCommitAsync(backendManager).ConfigureAwait(false);
await backendManager.WaitForEmptyAsync(result.TaskControl.ProgressToken).ConfigureAwait(false);
await database.FlushBackendMessagesAndCommitAsync(backendManager).ConfigureAwait(false);
// Grab the size of the last uploaded volume
return backendManager.LastWriteSize;
}
catch (RetiredException)
{
}
return -1;
}
public async Task RunAsync(string[] sources, IBackendManager backendManager, IFilter filter)
@@ -719,7 +715,7 @@ namespace Duplicati.Library.Main.Operation
// Wait for upload completion
m_result.OperationProgressUpdater.UpdatePhase(OperationPhase.Backup_WaitForUpload);
var lastVolumeSize = await FlushBackend(db, m_result, backendManager).ConfigureAwait(false);
await FlushBackend(db, m_result, backendManager).ConfigureAwait(false);
if (!m_options.Dryrun)
database.TerminatedWithActiveUploads = false;
@@ -730,7 +726,10 @@ namespace Duplicati.Library.Main.Operation
{
// If this throws, we should roll back the transaction
if (await m_result.TaskControl.ProgressRendevouz().ConfigureAwait(false))
{
var lastVolumeSize = m_database.GetLastWrittenDBlockVolumeSize(rtr.Transaction);
await CompactIfRequired(backendManager, rtr, lastVolumeSize);
}
if (m_options.UploadVerificationFile && await m_result.TaskControl.ProgressRendevouz().ConfigureAwait(false))
{
+1 -1
View File
@@ -18,7 +18,7 @@
<Link>changelog.txt</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="..\..\LICENSE.txt">
<Content Include="..\..\LICENSE">
<Link>licenses\license.txt</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -17,9 +17,9 @@
translate-params-mail1="'mailto:kenneth@duplicati.com'"
translate-params-mail2="'mailto:rene@duplicati.com'"
translate-params-websitename="'duplicati.com'"
translate-params-websitelink="'http://www.duplicati.com'"
translate-params-websitelink="'https://duplicati.com'"
translate-params-licensename="'MIT license'"
translate-params-licenselink="'https://raw.githubusercontent.com/duplicati/duplicati/master/LICENSE.txt'"
translate-params-licenselink="'https://raw.githubusercontent.com/duplicati/duplicati/master/LICENSE'"
>
{{appname}} was primarily developed by <a href="{{mail1}}">{{dev1}}</a> and <a href="{{mail2}}">{{dev2}}</a>. {{appname}} can be downloaded from <a href="{{websitelink}}">{{websitename}}</a>. {{appname}} is licensed under the <a href="{{licenselink}}">{{licensename}}</a>.
</div>
+9
View File
@@ -741,6 +741,9 @@ namespace Duplicati.UnitTest
using (var c = new Controller("file://" + TARGETFOLDER, testopts, null))
TestUtils.AssertResults(c.Backup(new string[] { DATAFOLDER }));
// Ensure that the target folder only has a single dlist file
Assert.AreEqual(1, Directory.EnumerateFiles(TARGETFOLDER, "*.dlist.*").Count(), "There should be only one dlist file in the target folder");
// Make a new backup that fails uploading a dblock file
ModifySourceFiles();
@@ -753,6 +756,7 @@ namespace Duplicati.UnitTest
var secondUploadCompleted = false;
// Fail the compact after the first dblock put is completed
var uploads = new List<string>();
DeterministicErrorBackend.ErrorGenerator = (DeterministicErrorBackend.BackendAction action, string remotename) =>
{
if (action.IsGetOperation)
@@ -783,6 +787,11 @@ namespace Duplicati.UnitTest
Assert.That(secondUploadStarted, Is.True, "Second upload was not started");
Assert.That(secondUploadCompleted, Is.True, "Second upload was not started");
Assert.That(hasFailed, Is.True, "Failed to fail the upload");
Assert.That(!uploads.Any(x => x.Contains("dlist")), Is.True, "Upload of dlist file was not skipped");
// Ensure that the target folder only has a single dlist file
Assert.AreEqual(1, Directory.EnumerateFiles(TARGETFOLDER, "*.dlist.*").Count(), $"There should be only one dlist file in the target folder: {string.Join(", ", uploads)}");
// Create a regular backup
using (var c = new Controller("file://" + TARGETFOLDER, testopts, null))
@@ -819,7 +819,7 @@ public static partial class Command
// Write the license file
File.Copy(
Path.Combine(baseDir, "LICENSE.txt"),
Path.Combine(baseDir, "LICENSE"),
EnsureFolderForFile(
Path.Combine(pkgroot, "usr", "share", "doc", "duplicati", "copyright")
)