From 44653f506eb48c271fc4337dc9379d37222b127a Mon Sep 17 00:00:00 2001 From: Kenneth Skovhede Date: Mon, 12 May 2025 14:44:03 +0200 Subject: [PATCH] Fixed retries when token times out. This fixes #5904 --- .../ServerUtil/Commands/RunBackup.cs | 48 ++++++++++++++++++- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/Duplicati/CommandLine/ServerUtil/Commands/RunBackup.cs b/Duplicati/CommandLine/ServerUtil/Commands/RunBackup.cs index 70fc00fa9..7e569b1fa 100644 --- a/Duplicati/CommandLine/ServerUtil/Commands/RunBackup.cs +++ b/Duplicati/CommandLine/ServerUtil/Commands/RunBackup.cs @@ -57,14 +57,15 @@ public static class RunBackup if (!quiet) output.AppendConsoleMessage($"Running backup {matchingBackup.Name} (ID: {matchingBackup.ID})"); - + await connection.RunBackup(matchingBackup.ID); if (wait) { if (!quiet) output.AppendConsoleMessage("Waiting for backup to finish..."); - await connection.WaitForBackup(matchingBackup.ID, TimeSpan.FromSeconds(pollinterval), msg => + + await WaitForBackupWithRetries(connection, settings, matchingBackup.ID, pollinterval, output, msg => { if (!quiet) output.AppendConsoleMessage($"[{DateTime.Now}]: {msg}"); @@ -75,4 +76,47 @@ public static class RunBackup } output.SetResult(true); })); + + /// + /// Waits for a backup to finish with retries + /// + /// The connection to use + /// The settings to use + /// The ID of the backup to wait for + /// The interval in seconds to poll for backup status + /// The output interceptor to use + /// The action to perform on each poll + /// A task that represents the asynchronous operation + private static async Task WaitForBackupWithRetries(Connection connection, Settings settings, string backupId, int pollInterval, OutputInterceptor output, Action onPoll) + { + var retry = true; + + while (retry) + { + try + { + await connection.WaitForBackup(backupId, TimeSpan.FromSeconds(pollInterval), onPoll); + return; + } + catch (Exception) + { + retry = false; + try + { + // See if we can get a new connection (re-connect) + onPoll("Re-authenticating..."); + connection = await settings.GetConnection(output); + retry = true; + } + catch (Exception) + { + } + + // Throw original exception if we can't re-connect + if (!retry) + throw; + } + + } while (retry) ; + } }