[PictureLoader] Reduce downtime between load attempts

This commit is contained in:
RickyRister 2025-07-03 23:15:56 -07:00
parent 67a3b03b07
commit fd3467a14e
2 changed files with 24 additions and 8 deletions

View file

@ -12,7 +12,10 @@
#include <QThread> #include <QThread>
#include <utility> #include <utility>
PictureLoaderWorker::PictureLoaderWorker() : QObject(nullptr), picDownload(SettingsCache::instance().getPicDownload()) static constexpr int MAX_REQUESTS_PER_SEC = 10;
PictureLoaderWorker::PictureLoaderWorker()
: QObject(nullptr), picDownload(SettingsCache::instance().getPicDownload()), requestCounter(MAX_REQUESTS_PER_SEC)
{ {
networkManager = new QNetworkAccessManager(this); networkManager = new QNetworkAccessManager(this);
// We need a timeout to ensure requests don't hang indefinitely in case of // We need a timeout to ensure requests don't hang indefinitely in case of
@ -48,7 +51,7 @@ PictureLoaderWorker::PictureLoaderWorker() : QObject(nullptr), picDownload(Setti
connect(this, &PictureLoaderWorker::imageLoadEnqueued, this, &PictureLoaderWorker::handleImageLoadEnqueued); connect(this, &PictureLoaderWorker::imageLoadEnqueued, this, &PictureLoaderWorker::handleImageLoadEnqueued);
connect(&requestTimer, &QTimer::timeout, this, &PictureLoaderWorker::processQueuedRequests); connect(&requestTimer, &QTimer::timeout, this, &PictureLoaderWorker::resetRequestCounter);
requestTimer.setInterval(1000); requestTimer.setInterval(1000);
requestTimer.start(); requestTimer.start();
} }
@ -70,6 +73,7 @@ void PictureLoaderWorker::queueRequest(const QUrl &url, PictureLoaderWorkerWork
} else { } else {
requestLoadQueue.append(qMakePair(url, worker)); requestLoadQueue.append(qMakePair(url, worker));
emit imageLoadQueued(url, worker); emit imageLoadQueued(url, worker);
processQueuedRequests();
} }
} }
@ -95,22 +99,31 @@ QNetworkReply *PictureLoaderWorker::makeRequest(const QUrl &url, PictureLoaderWo
return reply; return reply;
} }
void PictureLoaderWorker::resetRequestCounter()
{
requestCounter = MAX_REQUESTS_PER_SEC;
processQueuedRequests();
}
void PictureLoaderWorker::processQueuedRequests() void PictureLoaderWorker::processQueuedRequests()
{ {
for (int i = 0; i < 10; i++) { while (requestCounter > 0 && processSingleRequest()) {
processSingleRequest(); --requestCounter;
} }
} }
/** /**
* Immediately processes a single queued request * Immediately processes a single queued request. No-ops if the load queue is empty
* @return If a request was processed
*/ */
void PictureLoaderWorker::processSingleRequest() bool PictureLoaderWorker::processSingleRequest()
{ {
if (!requestLoadQueue.isEmpty()) { if (!requestLoadQueue.isEmpty()) {
auto request = requestLoadQueue.takeFirst(); auto request = requestLoadQueue.takeFirst();
makeRequest(request.first, request.second); makeRequest(request.first, request.second);
return true;
} }
return false;
} }
void PictureLoaderWorker::enqueueImageLoad(const CardInfoPtr &card) void PictureLoaderWorker::enqueueImageLoad(const CardInfoPtr &card)

View file

@ -38,7 +38,7 @@ public:
public slots: public slots:
QNetworkReply *makeRequest(const QUrl &url, PictureLoaderWorkerWork *workThread); QNetworkReply *makeRequest(const QUrl &url, PictureLoaderWorkerWork *workThread);
void processQueuedRequests(); void processQueuedRequests();
void processSingleRequest(); bool processSingleRequest();
void imageLoadedSuccessfully(const CardInfoPtr &card, const QImage &image); void imageLoadedSuccessfully(const CardInfoPtr &card, const QImage &image);
void cacheRedirect(const QUrl &originalUrl, const QUrl &redirectUrl); void cacheRedirect(const QUrl &originalUrl, const QUrl &redirectUrl);
void removedCachedUrl(const QUrl &url); void removedCachedUrl(const QUrl &url);
@ -52,7 +52,9 @@ private:
static constexpr int CacheTTLInDays = 30; // TODO: Make user configurable static constexpr int CacheTTLInDays = 30; // TODO: Make user configurable
bool picDownload; bool picDownload;
QQueue<QPair<QUrl, PictureLoaderWorkerWork *>> requestLoadQueue; QQueue<QPair<QUrl, PictureLoaderWorkerWork *>> requestLoadQueue;
QTimer requestTimer; // Timer for processing delayed requests
int requestCounter;
QTimer requestTimer; // Timer for refreshing request counter
PictureLoaderLocal *localLoader; PictureLoaderLocal *localLoader;
QSet<CardInfoPtr> currentlyLoading; // for deduplication purposes QSet<CardInfoPtr> currentlyLoading; // for deduplication purposes
@ -63,6 +65,7 @@ private:
void cleanStaleEntries(); void cleanStaleEntries();
private slots: private slots:
void resetRequestCounter();
void handleImageLoadEnqueued(const CardInfoPtr &card); void handleImageLoadEnqueued(const CardInfoPtr &card);
signals: signals: