Added support to the scraper for automatically retrying on errors.

This commit is contained in:
Leon Styhre 2023-02-10 17:24:50 +01:00
parent 07951d8d21
commit e663a717f0
4 changed files with 35 additions and 45 deletions

View file

@ -942,30 +942,19 @@ void GuiScraperMenu::openOtherOptions()
->setOpacity(DISABLED_OPACITY);
}
// Retry search on peer verification errors (TLS/certificate issues).
auto scraperRetryPeerVerification = std::make_shared<SwitchComponent>();
scraperRetryPeerVerification->setState(
Settings::getInstance()->getBool("ScraperRetryPeerVerification"));
s->addWithLabel("AUTO-RETRY ON PEER VERIFICATION ERRORS", scraperRetryPeerVerification);
s->addSaveFunc([scraperRetryPeerVerification, s] {
if (scraperRetryPeerVerification->getState() !=
Settings::getInstance()->getBool("ScraperRetryPeerVerification")) {
Settings::getInstance()->setBool("ScraperRetryPeerVerification",
scraperRetryPeerVerification->getState());
// Automatic retry on error.
auto scraperRetryOnError = std::make_shared<SwitchComponent>();
scraperRetryOnError->setState(Settings::getInstance()->getBool("ScraperRetryOnError"));
s->addWithLabel("AUTOMATIC RETRY ON ERROR", scraperRetryOnError);
s->addSaveFunc([scraperRetryOnError, s] {
if (scraperRetryOnError->getState() !=
Settings::getInstance()->getBool("ScraperRetryOnError")) {
Settings::getInstance()->setBool("ScraperRetryOnError",
scraperRetryOnError->getState());
s->setNeedsSaving();
}
});
// The TLS/certificate issue is not present for TheGamesDB, so gray out the option if this
// scraper is selected.
if (Settings::getInstance()->getString("Scraper") == "thegamesdb") {
scraperRetryPeerVerification->setEnabled(false);
scraperRetryPeerVerification->setOpacity(DISABLED_OPACITY);
scraperRetryPeerVerification->getParent()
->getChild(scraperRetryPeerVerification->getChildIndex() - 1)
->setOpacity(DISABLED_OPACITY);
}
// Switch callbacks.
auto interactiveToggleFunc = [scraperSemiautomatic]() {
if (scraperSemiautomatic->getEnabled()) {

View file

@ -34,24 +34,24 @@
#include "resources/Font.h"
#include "utils/StringUtil.h"
#define FAILED_VERIFICATION_RETRIES 8
GuiScraperSearch::GuiScraperSearch(SearchType type, unsigned int scrapeCount)
: mRenderer {Renderer::getInstance()}
, mGrid {glm::ivec2 {5, 3}}
, mSearchType {type}
, mScrapeCount {scrapeCount}
, mRefinedSearch {false}
, mBlockAccept {false}
, mAcceptedResult {false}
, mFoundGame {false}
, mScrapeRatings {false}
, mRetrySearch {false}
, mRetryCount {0}
, mRetryTimer {glm::clamp(
Settings::getInstance()->getInt("ScraperRetryOnErrorTimer") * 1000, 1000, 60000)}
, mRetryAccumulator {0}
{
addChild(&mGrid);
mBlockAccept = false;
mAcceptedResult = false;
mRetrySearch = false;
mRetryCount = 0;
mWindow->setAllowTextScrolling(true);
// Left spacer (empty component, needed for borders).
@ -498,21 +498,14 @@ void GuiScraperSearch::onSearchDone(std::vector<ScraperSearchResult>& results)
void GuiScraperSearch::onSearchError(const std::string& error, HttpReq::Status status)
{
// This is a workaround for a somehow frequently recurring issue with screenscraper.fr
// where requests to download the thumbnails are randomly met with TLS verification errors.
// It's unclear why it only happens to the thumbnail requests, but it usually goes away
// after a few days or so. If this issue occurs and the corresponding setting has been
// enabled, we'll retry the search automatically up to FAILED_VERIFICATION_RETRIES number
// of times. Usually a few retries is enough to get the thumbnail to download. If not,
// the error dialog will be presented to the user, and if the "Retry" button is pressed,
// a new round of retries will take place.
if (status == HttpReq::REQ_FAILED_VERIFICATION && mRetryCount < FAILED_VERIFICATION_RETRIES &&
Settings::getInstance()->getBool("ScraperRetryPeerVerification")) {
const int retries {
glm::clamp(Settings::getInstance()->getInt("ScraperRetryOnErrorCount"), 1, 20)};
if (Settings::getInstance()->getBool("ScraperRetryOnError") && mRetryCount < retries) {
LOG(LogError) << "GuiScraperSearch: " << Utils::String::replace(error, "\n", "");
mRetrySearch = true;
++mRetryCount;
LOG(LogError) << "GuiScraperSearch: Attempting automatic retry " << mRetryCount << " of "
<< FAILED_VERIFICATION_RETRIES;
<< retries;
return;
}
else {
@ -688,17 +681,21 @@ void GuiScraperSearch::update(int deltaTime)
{
GuiComponent::update(deltaTime);
// There was a failure and we're attempting an automatic retry.
if (mBlockAccept)
mBusyAnim.update(deltaTime);
if (mRetrySearch) {
// There was an error and we're attempting an automatic retry.
mRetryAccumulator += deltaTime;
if (mRetryAccumulator < mRetryTimer)
return;
mRetrySearch = false;
mRetryAccumulator = 0;
stop();
search(mLastSearch);
return;
}
if (mBlockAccept)
mBusyAnim.update(deltaTime);
// Check if the thumbnail for the currently selected game has finished downloading.
if (mScraperResults.size() > 0) {
auto it =

View file

@ -171,7 +171,9 @@ private:
bool mScrapeRatings;
bool mRetrySearch;
unsigned int mRetryCount;
int mRetryCount;
int mRetryTimer;
int mRetryAccumulator;
std::unique_ptr<ScraperSearchHandle> mSearchHandle;
std::unique_ptr<ScraperSearchHandle> mMDRetrieveURLsHandle;

View file

@ -148,7 +148,7 @@ void Settings::setDefaults()
mBoolMap["ScraperConvertUnderscores"] = {true, true};
mBoolMap["ScraperAutomaticRemoveDots"] = {true, true};
mBoolMap["ScraperRegionFallback"] = {true, true};
mBoolMap["ScraperRetryPeerVerification"] = {false, false};
mBoolMap["ScraperRetryOnError"] = {true, true};
// UI settings.
mStringMap["ThemeSet"] = {"slate-es-de", "slate-es-de"};
@ -319,8 +319,10 @@ void Settings::setDefaults()
mStringMap["UIMode_passkey"] = {"uuddlrlrba", "uuddlrlrba"};
mIntMap["LottieMaxFileCache"] = {150, 150};
mIntMap["LottieMaxTotalCache"] = {1024, 1024};
mIntMap["ScraperConnectionTimeout"] = {60, 60};
mIntMap["ScraperConnectionTimeout"] = {30, 30};
mIntMap["ScraperTransferTimeout"] = {120, 120};
mIntMap["ScraperRetryOnErrorCount"] = {5, 5};
mIntMap["ScraperRetryOnErrorTimer"] = {5, 5};
//
// Hardcoded or program-internal settings.