Refactor retry logic to reduce code duplication

- Extract retry condition check into ShouldRetryRequest() helper
- Extract backoff delay calculation into CalculateBackoffDelay() helper
- Use helper methods in both GetRecentTracksRequestFinished and GetTopTracksRequestFinished
- Improves code maintainability and consistency

Co-authored-by: jonaski <10343810+jonaski@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-01-03 21:27:23 +00:00
parent 4c8103ef6d
commit 8bdbeeb5a8
2 changed files with 28 additions and 20 deletions

View File

@@ -49,6 +49,7 @@
#include "lastfmscrobbler.h" #include "lastfmscrobbler.h"
using namespace Qt::Literals::StringLiterals; using namespace Qt::Literals::StringLiterals;
using namespace ScrobblerSettings;
namespace { namespace {
constexpr int kRequestsDelay = 2000; constexpr int kRequestsDelay = 2000;
@@ -253,9 +254,8 @@ void LastFMImport::GetRecentTracksRequestFinished(QNetworkReply *reply, GetRecen
const JsonObjectResult json_object_result = ParseJsonObject(reply); const JsonObjectResult json_object_result = ParseJsonObject(reply);
if (!json_object_result.success()) { if (!json_object_result.success()) {
if (json_object_result.http_status_code == 500 || json_object_result.http_status_code == 503 || json_object_result.network_error == QNetworkReply::TemporaryNetworkFailureError) { if (ShouldRetryRequest(json_object_result) && request.retry_count < kMaxRetries) {
if (request.retry_count < kMaxRetries) { const int delay_ms = CalculateBackoffDelay(request.retry_count);
const int delay_ms = kInitialBackoffMs * (1 << request.retry_count);
qLog(Warning) << "Last.fm request failed with status" << json_object_result.http_status_code << ", retrying in" << delay_ms << "ms (attempt" << (request.retry_count + 1) << "of" << kMaxRetries << ")"; qLog(Warning) << "Last.fm request failed with status" << json_object_result.http_status_code << ", retrying in" << delay_ms << "ms (attempt" << (request.retry_count + 1) << "of" << kMaxRetries << ")";
QTimer::singleShot(delay_ms, this, [this, request]() { QTimer::singleShot(delay_ms, this, [this, request]() {
GetRecentTracksRequest retry_request(request.page, request.retry_count + 1); GetRecentTracksRequest retry_request(request.page, request.retry_count + 1);
@@ -263,7 +263,6 @@ void LastFMImport::GetRecentTracksRequestFinished(QNetworkReply *reply, GetRecen
}); });
return; return;
} }
}
Error(json_object_result.error_message); Error(json_object_result.error_message);
return; return;
} }
@@ -422,9 +421,8 @@ void LastFMImport::GetTopTracksRequestFinished(QNetworkReply *reply, GetTopTrack
const JsonObjectResult json_object_result = ParseJsonObject(reply); const JsonObjectResult json_object_result = ParseJsonObject(reply);
if (!json_object_result.success()) { if (!json_object_result.success()) {
if (json_object_result.http_status_code == 500 || json_object_result.http_status_code == 503 || json_object_result.network_error == QNetworkReply::TemporaryNetworkFailureError) { if (ShouldRetryRequest(json_object_result) && request.retry_count < kMaxRetries) {
if (request.retry_count < kMaxRetries) { const int delay_ms = CalculateBackoffDelay(request.retry_count);
const int delay_ms = kInitialBackoffMs * (1 << request.retry_count);
qLog(Warning) << "Last.fm request failed with status" << json_object_result.http_status_code << ", retrying in" << delay_ms << "ms (attempt" << (request.retry_count + 1) << "of" << kMaxRetries << ")"; qLog(Warning) << "Last.fm request failed with status" << json_object_result.http_status_code << ", retrying in" << delay_ms << "ms (attempt" << (request.retry_count + 1) << "of" << kMaxRetries << ")";
QTimer::singleShot(delay_ms, this, [this, request]() { QTimer::singleShot(delay_ms, this, [this, request]() {
GetTopTracksRequest retry_request(request.page, request.retry_count + 1); GetTopTracksRequest retry_request(request.page, request.retry_count + 1);
@@ -432,7 +430,6 @@ void LastFMImport::GetTopTracksRequestFinished(QNetworkReply *reply, GetTopTrack
}); });
return; return;
} }
}
Error(json_object_result.error_message); Error(json_object_result.error_message);
return; return;
} }
@@ -548,6 +545,14 @@ void LastFMImport::GetTopTracksRequestFinished(QNetworkReply *reply, GetTopTrack
} }
bool LastFMImport::ShouldRetryRequest(const JsonObjectResult &result) const {
return result.http_status_code == 500 || result.http_status_code == 503 || result.network_error == QNetworkReply::TemporaryNetworkFailureError;
}
int LastFMImport::CalculateBackoffDelay(const int retry_count) const {
return kInitialBackoffMs * (1 << retry_count);
}
void LastFMImport::UpdateTotalCheck() { void LastFMImport::UpdateTotalCheck() {
Q_EMIT UpdateTotal(lastplayed_total_, playcount_total_); Q_EMIT UpdateTotal(lastplayed_total_, playcount_total_);

View File

@@ -80,6 +80,9 @@ class LastFMImport : public JsonBaseRequest {
void SendGetRecentTracksRequest(GetRecentTracksRequest request); void SendGetRecentTracksRequest(GetRecentTracksRequest request);
void SendGetTopTracksRequest(GetTopTracksRequest request); void SendGetTopTracksRequest(GetTopTracksRequest request);
bool ShouldRetryRequest(const JsonObjectResult &result) const;
int CalculateBackoffDelay(const int retry_count) const;
void Error(const QString &error, const QVariant &debug = QVariant()) override; void Error(const QString &error, const QVariant &debug = QVariant()) override;
void UpdateTotalCheck(); void UpdateTotalCheck();