From 354dac65c2d168b0d211665285d5470d4977efcb Mon Sep 17 00:00:00 2001 From: Lee Watson Date: Thu, 28 Apr 2016 18:48:27 +0100 Subject: [PATCH 1/7] Fixed random timeout issues causing the whole program to hang until restart. Don't ignore curl dude, it has some quite useful error information :) --- audioscrobbler.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/audioscrobbler.cpp b/audioscrobbler.cpp index 00355fd..1cdbd4c 100644 --- a/audioscrobbler.cpp +++ b/audioscrobbler.cpp @@ -55,7 +55,15 @@ void CAudioScrobbler::OpenURL(std::string url, const char* postfields = 0, char* curl_easy_setopt(_handle, CURLOPT_ERRORBUFFER, errbuf); curl_easy_setopt(_handle, CURLOPT_URL, url.c_str()); - curl_easy_perform(_handle); + CURLcode res = curl_easy_perform(_handle); + + // Sometimes last.fm likes to just timeout for no reason, leaving us hanging. If this happens, completely refresh the curl handle. + if (res == CURLE_OPERATION_TIMEDOUT) { + eprintf("libcurl: (%d)", res); + eprintf("%s", curl_easy_strerror(res)); + curl_easy_cleanup(_handle); + _handle = curl_easy_init(); + } } From b52c5dce6edd4b5d222d02f5a38520165779c09d Mon Sep 17 00:00:00 2001 From: Lee Watson Date: Thu, 28 Apr 2016 18:57:31 +0100 Subject: [PATCH 2/7] Actually add a timeout --- audioscrobbler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/audioscrobbler.cpp b/audioscrobbler.cpp index 1cdbd4c..cd348db 100644 --- a/audioscrobbler.cpp +++ b/audioscrobbler.cpp @@ -44,6 +44,7 @@ void CAudioScrobbler::OpenURL(std::string url, const char* postfields = 0, char* curl_easy_setopt(_handle, CURLOPT_DNS_CACHE_TIMEOUT, 0); curl_easy_setopt(_handle, CURLOPT_NOPROGRESS, 1); curl_easy_setopt(_handle, CURLOPT_WRITEFUNCTION, writecb); + curl_easy_setopt(_handle, CURLOPT_TIMEOUT, 10); if(postfields) { curl_easy_setopt(_handle, CURLOPT_POST, 1); From 62aa9532bea02a47cbc9544794a1cb1ed8594fc0 Mon Sep 17 00:00:00 2001 From: Lee Watson Date: Thu, 28 Apr 2016 22:01:57 +0100 Subject: [PATCH 3/7] Retry rather than just giving up --- audioscrobbler.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/audioscrobbler.cpp b/audioscrobbler.cpp index cd348db..8f0dd88 100644 --- a/audioscrobbler.cpp +++ b/audioscrobbler.cpp @@ -2,6 +2,8 @@ #define APIKEY "a0ed2629d3d28606f67d7214c916788d" #define SECRET "295f31c5d28215215b1503fb0327cc01" +#define CURL_MAX_RETRIES 3 +#define CURL_RETRY_DELAY 3 // Seconds CAudioScrobbler* AudioScrobbler = 0; @@ -58,12 +60,22 @@ void CAudioScrobbler::OpenURL(std::string url, const char* postfields = 0, char* curl_easy_setopt(_handle, CURLOPT_URL, url.c_str()); CURLcode res = curl_easy_perform(_handle); - // Sometimes last.fm likes to just timeout for no reason, leaving us hanging. If this happens, completely refresh the curl handle. - if (res == CURLE_OPERATION_TIMEDOUT) { + // Sometimes last.fm likes to just timeout for no reason, leaving us hanging. + // If this happens, retry a few times with a small delay. + if (res != CURLE_OK) { eprintf("libcurl: (%d)", res); eprintf("%s", curl_easy_strerror(res)); - curl_easy_cleanup(_handle); - _handle = curl_easy_init(); + eprintf("Will retry %d times with a %d second delay.", CURL_MAX_RETRIES, CURL_RETRY_DELAY); + + int retries = 0; + do { + sleep(CURL_RETRY_DELAY); + retries++; + eprintf("Retry %d/%d", retries, CURL_MAX_RETRIES); + res = curl_easy_perform(_handle); + } while (retries < CURL_MAX_RETRIES); + + eprintf("Failed after %d retries, try again later.", CURL_MAX_RETRIES); } } From e8a60a1fbd5b5e54b5f7a4d9e32838a6846eab81 Mon Sep 17 00:00:00 2001 From: Lee Watson Date: Thu, 28 Apr 2016 22:03:42 +0100 Subject: [PATCH 4/7] Check the result of curl rather than just blindly retrying --- audioscrobbler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/audioscrobbler.cpp b/audioscrobbler.cpp index 8f0dd88..3a619b1 100644 --- a/audioscrobbler.cpp +++ b/audioscrobbler.cpp @@ -73,7 +73,7 @@ void CAudioScrobbler::OpenURL(std::string url, const char* postfields = 0, char* retries++; eprintf("Retry %d/%d", retries, CURL_MAX_RETRIES); res = curl_easy_perform(_handle); - } while (retries < CURL_MAX_RETRIES); + } while (res != CURLE_OK || retries < CURL_MAX_RETRIES); eprintf("Failed after %d retries, try again later.", CURL_MAX_RETRIES); } From 8506d510311a86e6a2bf6012f6cfed4a3c100090 Mon Sep 17 00:00:00 2001 From: Lee Watson Date: Thu, 28 Apr 2016 22:04:34 +0100 Subject: [PATCH 5/7] || -> && --- audioscrobbler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/audioscrobbler.cpp b/audioscrobbler.cpp index 3a619b1..bd10839 100644 --- a/audioscrobbler.cpp +++ b/audioscrobbler.cpp @@ -73,7 +73,7 @@ void CAudioScrobbler::OpenURL(std::string url, const char* postfields = 0, char* retries++; eprintf("Retry %d/%d", retries, CURL_MAX_RETRIES); res = curl_easy_perform(_handle); - } while (res != CURLE_OK || retries < CURL_MAX_RETRIES); + } while (res != CURLE_OK && retries < CURL_MAX_RETRIES); eprintf("Failed after %d retries, try again later.", CURL_MAX_RETRIES); } From 14c96f0b8f4c334ba6ca3c40b4c9ea7354b2b19c Mon Sep 17 00:00:00 2001 From: Lee Watson Date: Thu, 28 Apr 2016 22:30:56 +0100 Subject: [PATCH 6/7] Don't unconditially error --- audioscrobbler.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/audioscrobbler.cpp b/audioscrobbler.cpp index bd10839..c3f477e 100644 --- a/audioscrobbler.cpp +++ b/audioscrobbler.cpp @@ -75,7 +75,10 @@ void CAudioScrobbler::OpenURL(std::string url, const char* postfields = 0, char* res = curl_easy_perform(_handle); } while (res != CURLE_OK && retries < CURL_MAX_RETRIES); - eprintf("Failed after %d retries, try again later.", CURL_MAX_RETRIES); + // Still failing? + if (res != CURLE_OK) { + eprintf("Failed after %d retries, try again later.", CURL_MAX_RETRIES); + } } } From c8cd969719450969ab2d188b8c35cfbcae0941d7 Mon Sep 17 00:00:00 2001 From: Lee Watson Date: Thu, 28 Apr 2016 22:36:46 +0100 Subject: [PATCH 7/7] Cleaner user feedback --- audioscrobbler.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/audioscrobbler.cpp b/audioscrobbler.cpp index c3f477e..f4fd504 100644 --- a/audioscrobbler.cpp +++ b/audioscrobbler.cpp @@ -72,13 +72,12 @@ void CAudioScrobbler::OpenURL(std::string url, const char* postfields = 0, char* sleep(CURL_RETRY_DELAY); retries++; eprintf("Retry %d/%d", retries, CURL_MAX_RETRIES); + res = curl_easy_perform(_handle); + if (res != CURLE_OK) { + eprintf("Failed: %s", curl_easy_strerror(res)); + } } while (res != CURLE_OK && retries < CURL_MAX_RETRIES); - - // Still failing? - if (res != CURLE_OK) { - eprintf("Failed after %d retries, try again later.", CURL_MAX_RETRIES); - } } }