From 468c3b76de597d1140e363f5c01443e8ba459a0d Mon Sep 17 00:00:00 2001 From: sithlord48 Date: Tue, 24 Mar 2026 21:15:56 -0400 Subject: [PATCH] feat: backoff retry after number of retries --- docs/user/configuration.md | 19 +++++++------ src/lib/common/Settings.h | 5 +++- src/lib/deskflow/ClientApp.cpp | 33 ++++++++++++++++------ src/lib/deskflow/ClientApp.h | 7 +++++ src/lib/gui/dialogs/ClientConfigDialog.cpp | 14 +++++++-- src/lib/gui/dialogs/ClientConfigDialog.ui | 18 ++++++++++++ translations/deskflow_es.ts | 8 ++++++ translations/deskflow_it.ts | 8 ++++++ translations/deskflow_ja.ts | 8 ++++++ translations/deskflow_ko.ts | 8 ++++++ translations/deskflow_ru.ts | 8 ++++++ translations/deskflow_zh_CN.ts | 8 ++++++ 12 files changed, 124 insertions(+), 20 deletions(-) diff --git a/docs/user/configuration.md b/docs/user/configuration.md index 8ac701328..6fe3e491a 100644 --- a/docs/user/configuration.md +++ b/docs/user/configuration.md @@ -50,15 +50,16 @@ option=value This section contains options used when in client mode. It will begin with `[client]` -| Option | Valid Values | Description | -|:------------------|:------------------:|:-----------| -| languageSync | `true` or `false` | Sync to server language [default: true] | -| remoteHost | `IP` or `hostname` | The remote host(s) to connect to. Use a comma separated list when you want to try several hosts | -| yScrollScale | Double 0.1 - 10.0 | Vertical mouse scrolling will be scaled by this amount on the client [default: 1.0] | -| xScrollScale | Double 0.1 - 10.0 | Horizontal mouse scrolling will be scaled by this amount on the client [default: 1.0] | -| invertYScroll | `true` or `false` | Invert vertical scroll on this client [default: false] | -| invertXScroll | `true` or `false` | Invert horizontal scroll on this client [default: false] | -| xdpRestoreToken | UUID | Restore token provided by XDG portals | +| Option | Valid Values | Description | +|:--------------------------|:------------------:|:-----------| +| dynamicConnectionInterval | `true` or `false` | Use dynamic connection retry times based on number of previously failed attempts [default: false] | +| languageSync | `true` or `false` | Sync to server language [default: true] | +| remoteHost | `IP` or `hostname` | The remote host(s) to connect to. Use a comma separated list when you want to try several hosts | +| yScrollScale | Double 0.1 - 10.0 | Vertical mouse scrolling will be scaled by this amount on the client [default: 1.0] | +| xScrollScale | Double 0.1 - 10.0 | Horizontal mouse scrolling will be scaled by this amount on the client [default: 1.0] | +| invertYScroll | `true` or `false` | Invert vertical scroll on this client [default: false] | +| invertXScroll | `true` or `false` | Invert horizontal scroll on this client [default: false] | +| xdpRestoreToken | UUID | Restore token provided by XDG portals | ### Core diff --git a/src/lib/common/Settings.h b/src/lib/common/Settings.h index d06f0d052..5e7ee0f0e 100644 --- a/src/lib/common/Settings.h +++ b/src/lib/common/Settings.h @@ -34,6 +34,7 @@ public: struct Client { + inline static const auto DynamicConnectionRetry = QStringLiteral("client/dynamicConnectionInterval"); inline static const auto InvertYScroll = QStringLiteral("client/invertYScroll"); inline static const auto InvertXScroll = QStringLiteral("client/invertXScroll"); inline static const auto YScrollScale = QStringLiteral("client/yScrollScale"); @@ -198,7 +199,8 @@ private: }; inline static const QStringList m_validKeys = { - Settings::Client::InvertYScroll + Settings::Client::DynamicConnectionRetry + , Settings::Client::InvertYScroll , Settings::Client::InvertXScroll , Settings::Client::LanguageSync , Settings::Client::RemoteHost @@ -260,6 +262,7 @@ private: , Settings::Core::UseWlClipboard , Settings::Core::EnableEnterCommand , Settings::Core::EnableExitCommand + , Settings::Client::DynamicConnectionRetry , Settings::Server::ExternalConfig , Settings::Client::InvertYScroll , Settings::Client::InvertXScroll diff --git a/src/lib/deskflow/ClientApp.cpp b/src/lib/deskflow/ClientApp.cpp index f00515962..70b9d1b43 100644 --- a/src/lib/deskflow/ClientApp.cpp +++ b/src/lib/deskflow/ClientApp.cpp @@ -45,8 +45,6 @@ #include -constexpr static auto s_retryTime = 1.0; - ClientApp::ClientApp(IEventQueue *events, const QString &processName) : App(events, processName) { // do nothing @@ -164,8 +162,8 @@ void ClientApp::handleClientRestart(const Event &, EventQueueTimer *timer) void ClientApp::scheduleClientRestart(double retryTime) { - // install a timer and handler to retry later LOG_DEBUG("retry in %.0f seconds", retryTime); + // install a timer and handler to retry later EventQueueTimer *timer = getEvents()->newOneShotTimer(retryTime, nullptr); getEvents()->addHandler(EventTypes::Timer, timer, [this, timer](const auto &e) { handleClientRestart(e, timer); }); } @@ -186,7 +184,7 @@ void ClientApp::handleClientFailed(const Event &e) LOG_WARN("failed to connect to server=%s, trying next resolved address", info->m_what.c_str()); if (!m_suspended) { - scheduleClientRestart(s_retryTime); + scheduleClientRestart(retryTime()); } } else { // All resolved addresses exhausted, try next server in list @@ -200,7 +198,7 @@ void ClientApp::handleClientFailed(const Event &e) std::unique_ptr info(static_cast(e.getData())); LOG_WARN("failed to connect to server=%s, trying next server in list", info->m_what.c_str()); if (!m_suspended) { - scheduleClientRestart(s_retryTime); + scheduleClientRestart(retryTime()); } } } @@ -216,16 +214,18 @@ void ClientApp::handleClientRefused(const Event &e) } else { LOG_WARN("failed to connect to server: %s", info->m_what.c_str()); if (!m_suspended) { - scheduleClientRestart(s_retryTime); + m_retryCount++; + scheduleClientRestart(retryTime()); } } } void ClientApp::handleClientDisconnected() { + m_retryCount = 0; LOG_IPC("disconnected from server"); if (!m_suspended) { - scheduleClientRestart(s_retryTime); + scheduleClientRestart(retryTime()); } } @@ -299,7 +299,7 @@ bool ClientApp::startClient() return false; } - scheduleClientRestart(s_retryTime); + scheduleClientRestart(retryTime()); return true; } @@ -393,3 +393,20 @@ ISocketFactory *ClientApp::getSocketFactory() const { return new TCPSocketFactory(getEvents(), getSocketMultiplexer()); } + +double ClientApp::retryTime() const +{ + if (!Settings::value(Settings::Client::DynamicConnectionRetry).toBool() || m_retryCount < 300) // 5 minutes + return 1; + if (m_retryCount < 360) // 5 minutes + return 5; + if (m_retryCount < 390) // 5 minutes + return 10; + if (m_retryCount < 410) // 10 minutes + return 30; + if (m_retryCount < 420) // 10 minutes + return 60; + if (m_retryCount < 430) // 20 minutes + return 120; + return 300; +} diff --git a/src/lib/deskflow/ClientApp.h b/src/lib/deskflow/ClientApp.h index f38379ba8..27c8a4616 100644 --- a/src/lib/deskflow/ClientApp.h +++ b/src/lib/deskflow/ClientApp.h @@ -78,6 +78,12 @@ public: return (ClientApp &)App::instance(); } + /** + * @brief retryTime + * @return next retry time based on number of current retries + */ + double retryTime() const; + private: ISocketFactory *getSocketFactory() const; NetworkAddress &getCurrentServerAddress(); @@ -89,4 +95,5 @@ private: QList m_serverAddresses; size_t m_currentServerIndex = 0; size_t m_lastServerAddressIndex = 0; + uint m_retryCount = 0; }; diff --git a/src/lib/gui/dialogs/ClientConfigDialog.cpp b/src/lib/gui/dialogs/ClientConfigDialog.cpp index 02a6e7250..12503fb5f 100644 --- a/src/lib/gui/dialogs/ClientConfigDialog.cpp +++ b/src/lib/gui/dialogs/ClientConfigDialog.cpp @@ -52,6 +52,9 @@ void ClientConfigDialog::initConnections() const &ClientConfigDialog::resetToDefault ); + connect( + ui->cbDynamicConnectTime, &QCheckBox::checkStateChanged, this, &ClientConfigDialog::setButtonBoxEnabledButtons + ); connect(ui->cbLanguageSync, &QCheckBox::checkStateChanged, this, &ClientConfigDialog::setButtonBoxEnabledButtons); connect(ui->cbYScrollInvert, &QCheckBox::checkStateChanged, this, &ClientConfigDialog::setButtonBoxEnabledButtons); connect(ui->sbYScrollScale, &QDoubleSpinBox::valueChanged, this, &ClientConfigDialog::setButtonBoxEnabledButtons); @@ -61,7 +64,9 @@ void ClientConfigDialog::initConnections() const bool ClientConfigDialog::isModified() const { - return (ui->cbLanguageSync->isChecked() != Settings::value(Settings::Client::LanguageSync).toBool()) || + return (ui->cbDynamicConnectTime->isChecked() != Settings::value(Settings::Client::DynamicConnectionRetry).toBool() + ) || + (ui->cbLanguageSync->isChecked() != Settings::value(Settings::Client::LanguageSync).toBool()) || (ui->cbYScrollInvert->isChecked() != Settings::value(Settings::Client::InvertYScroll).toBool()) || (ui->sbYScrollScale->value() != Settings::value(Settings::Client::YScrollScale).toDouble()) || (ui->cbXScrollInvert->isChecked() != Settings::value(Settings::Client::InvertXScroll).toBool()) || @@ -70,7 +75,9 @@ bool ClientConfigDialog::isModified() const bool ClientConfigDialog::isDefault() const { - return (ui->cbLanguageSync->isChecked() == Settings::defaultValue(Settings::Client::LanguageSync).toBool()) && + return (ui->cbDynamicConnectTime->isChecked() == + Settings::defaultValue(Settings::Client::DynamicConnectionRetry).toBool()) && + (ui->cbLanguageSync->isChecked() == Settings::defaultValue(Settings::Client::LanguageSync).toBool()) && (ui->cbYScrollInvert->isChecked() == Settings::defaultValue(Settings::Client::InvertYScroll).toBool()) && (ui->sbYScrollScale->value() == Settings::defaultValue(Settings::Client::YScrollScale).toDouble()) && (ui->cbXScrollInvert->isChecked() == Settings::defaultValue(Settings::Client::InvertXScroll).toBool()) && @@ -87,6 +94,7 @@ void ClientConfigDialog::setButtonBoxEnabledButtons() const void ClientConfigDialog::load() { + ui->cbDynamicConnectTime->setChecked(Settings::value(Settings::Client::DynamicConnectionRetry).toBool()); ui->cbLanguageSync->setChecked(Settings::value(Settings::Client::LanguageSync).toBool()); ui->cbYScrollInvert->setChecked(Settings::value(Settings::Client::InvertYScroll).toBool()); ui->sbYScrollScale->setValue(Settings::value(Settings::Client::YScrollScale).toDouble()); @@ -96,6 +104,7 @@ void ClientConfigDialog::load() void ClientConfigDialog::resetToDefault() { + ui->cbDynamicConnectTime->setChecked(Settings::defaultValue(Settings::Client::DynamicConnectionRetry).toBool()); ui->cbLanguageSync->setChecked(Settings::defaultValue(Settings::Client::LanguageSync).toBool()); ui->cbYScrollInvert->setChecked(Settings::defaultValue(Settings::Client::InvertYScroll).toBool()); ui->sbYScrollScale->setValue(Settings::defaultValue(Settings::Client::YScrollScale).toDouble()); @@ -105,6 +114,7 @@ void ClientConfigDialog::resetToDefault() void ClientConfigDialog::save() { + Settings::setValue(Settings::Client::DynamicConnectionRetry, ui->cbDynamicConnectTime->isChecked()); Settings::setValue(Settings::Client::LanguageSync, ui->cbLanguageSync->isChecked()); Settings::setValue(Settings::Client::InvertYScroll, ui->cbYScrollInvert->isChecked()); Settings::setValue(Settings::Client::YScrollScale, ui->sbYScrollScale->value()); diff --git a/src/lib/gui/dialogs/ClientConfigDialog.ui b/src/lib/gui/dialogs/ClientConfigDialog.ui index bf994e99f..f258ada8c 100644 --- a/src/lib/gui/dialogs/ClientConfigDialog.ui +++ b/src/lib/gui/dialogs/ClientConfigDialog.ui @@ -2,6 +2,14 @@ ClientConfigDialog + + + 0 + 0 + 391 + 176 + + 0 @@ -12,6 +20,16 @@ Client Configuration + + + + <html><head/><body><p>Allow the client to slow the rate it attempts to reconnect to the server when connections attempts are failing. The delay between connection attempts will start at 1 second intervals and can be a maxium of 5 minutes between connection attempts.</p></body></html> + + + Use dynamic reconnection time based on connection attempts + + + diff --git a/translations/deskflow_es.ts b/translations/deskflow_es.ts index 715925f0a..432b4ca97 100644 --- a/translations/deskflow_es.ts +++ b/translations/deskflow_es.ts @@ -185,6 +185,14 @@ p, li { white-space: pre-wrap; } Reset to default values Restablecer valores predeterminados + + <html><head/><body><p>Allow the client to slow the rate it attempts to reconnect to the server when connections attempts are failing. The delay between connection attempts will start at 1 second intervals and can be a maxium of 5 minutes between connection attempts.</p></body></html> + <html><head/><body><p>Permite que el cliente reduzca la frecuencia con la que intenta reconectarse al servidor cuando los intentos de conexión fallan. El intervalo entre intentos de conexión comenzará en 1 segundo y podrá alcanzar un máximo de 5 minutos.</p></body></html> + + + Use dynamic reconnection time based on connection attempts + Utilizar un tiempo de reconexión dinámico basado en los intentos de conexión + FingerprintDialog diff --git a/translations/deskflow_it.ts b/translations/deskflow_it.ts index 8e86830a1..388a433e1 100644 --- a/translations/deskflow_it.ts +++ b/translations/deskflow_it.ts @@ -185,6 +185,14 @@ p, li { white-space: pre-wrap; } Reset to default values Ripristina i valori predefiniti + + <html><head/><body><p>Allow the client to slow the rate it attempts to reconnect to the server when connections attempts are failing. The delay between connection attempts will start at 1 second intervals and can be a maxium of 5 minutes between connection attempts.</p></body></html> + <html><head/><body><p>Consente al client di rallentare la frequenza dei tentativi di riconnessione al server quando i tentativi di connessione falliscono. Il ritardo tra i tentativi di connessione inizierà a intervalli di 1 secondo, fino a raggiungere un massimo di 5 minuti tra un tentativo e l'altro.</p></body></html> + + + Use dynamic reconnection time based on connection attempts + Utilizza un tempo di riconnessione dinamico basato sui tentativi di connessione + FingerprintDialog diff --git a/translations/deskflow_ja.ts b/translations/deskflow_ja.ts index a4fa772d6..1400dec8a 100644 --- a/translations/deskflow_ja.ts +++ b/translations/deskflow_ja.ts @@ -185,6 +185,14 @@ p, li { white-space: pre-wrap; } Reset to default values デフォルト値にリセットする + + <html><head/><body><p>Allow the client to slow the rate it attempts to reconnect to the server when connections attempts are failing. The delay between connection attempts will start at 1 second intervals and can be a maxium of 5 minutes between connection attempts.</p></body></html> + <html><head/><body><p>接続試行が失敗している場合、クライアントがサーバーへの再接続を試みる頻度を徐々に落とせるようにします。接続試行の間隔は当初1秒から開始され、最大で5分まで延長されます。</p></body></html> + + + Use dynamic reconnection time based on connection attempts + 接続試行回数に基づき、再接続時間を動的に調整する + FingerprintDialog diff --git a/translations/deskflow_ko.ts b/translations/deskflow_ko.ts index f4b6826fd..8cb419243 100644 --- a/translations/deskflow_ko.ts +++ b/translations/deskflow_ko.ts @@ -185,6 +185,14 @@ p, li { white-space: pre-wrap; } Reset to default values 기본값으로 재설정 + + <html><head/><body><p>Allow the client to slow the rate it attempts to reconnect to the server when connections attempts are failing. The delay between connection attempts will start at 1 second intervals and can be a maxium of 5 minutes between connection attempts.</p></body></html> + <html><head/><body><p>연결 시도가 실패할 경우, 클라이언트가 서버 재연결 시도 주기를 늦추도록 허용합니다. 연결 시도 간 지연 시간은 1초 간격으로 시작되며, 최대 5분까지 늘어날 수 있습니다.</p></body></html> + + + Use dynamic reconnection time based on connection attempts + 연결 시도 횟수에 따라 동적 재연결 시간을 사용합니다 + FingerprintDialog diff --git a/translations/deskflow_ru.ts b/translations/deskflow_ru.ts index a319c2f96..c10b07175 100644 --- a/translations/deskflow_ru.ts +++ b/translations/deskflow_ru.ts @@ -185,6 +185,14 @@ p, li { white-space: pre-wrap; } Reset to default values Сбросить до значений по умолчанию + + <html><head/><body><p>Allow the client to slow the rate it attempts to reconnect to the server when connections attempts are failing. The delay between connection attempts will start at 1 second intervals and can be a maxium of 5 minutes between connection attempts.</p></body></html> + <html><head/><body><p>Позволить клиенту замедлять частоту попыток повторного подключения к серверу в случае неудачных попыток соединения. Интервал между попытками подключения будет начинаться с 1 секунды и может достигать максимума в 5 минут.</p></body></html> + + + Use dynamic reconnection time based on connection attempts + Использовать динамическое время переподключения в зависимости от попыток подключения + FingerprintDialog diff --git a/translations/deskflow_zh_CN.ts b/translations/deskflow_zh_CN.ts index 82c2c7855..5be1d8dc9 100644 --- a/translations/deskflow_zh_CN.ts +++ b/translations/deskflow_zh_CN.ts @@ -185,6 +185,14 @@ p, li { white-space: pre-wrap; } Reset to default values 重置为默认值 + + <html><head/><body><p>Allow the client to slow the rate it attempts to reconnect to the server when connections attempts are failing. The delay between connection attempts will start at 1 second intervals and can be a maxium of 5 minutes between connection attempts.</p></body></html> + <html><head/><body><p>允许客户端在连接尝试失败时,降低其重连服务器的频率。连接尝试之间的间隔将从 1 秒开始,最长可达 5 分钟。</p></body></html> + + + Use dynamic reconnection time based on connection attempts + 根据连接尝试次数,采用动态重连时间 + FingerprintDialog