From b2a532be62c66061d2c76447f0aca3b10d920e21 Mon Sep 17 00:00:00 2001 From: John Maguire Date: Mon, 20 Jul 2015 14:35:13 +0100 Subject: [PATCH] Experiment with typesafe time units --- ext/libclementine-common/core/closure.cpp | 10 ---------- ext/libclementine-common/core/closure.h | 16 +++++++++++++++- ext/libclementine-common/core/logging.cpp | 14 ++++++++++++++ ext/libclementine-common/core/logging.h | 5 +++++ src/internet/amazon/amazonclouddrive.cpp | 8 +++++--- 5 files changed, 39 insertions(+), 14 deletions(-) diff --git a/ext/libclementine-common/core/closure.cpp b/ext/libclementine-common/core/closure.cpp index 477c3868d..ff0ed120f 100644 --- a/ext/libclementine-common/core/closure.cpp +++ b/ext/libclementine-common/core/closure.cpp @@ -17,8 +17,6 @@ #include "closure.h" -#include - #include "core/timeconstants.h" namespace _detail { @@ -65,11 +63,3 @@ void DoInAMinuteOrSo(QObject* receiver, const char* slot) { int msec = (60 + (qrand() % 60)) * kMsecPerSec; DoAfter(receiver, slot, msec); } - -void DoAfter(std::function callback, int msec) { - QTimer* timer = new QTimer; - timer->setSingleShot(true); - NewClosure(timer, SIGNAL(timeout()), callback); - QObject::connect(timer, SIGNAL(timeout()), timer, SLOT(deleteLater())); - timer->start(msec); -} diff --git a/ext/libclementine-common/core/closure.h b/ext/libclementine-common/core/closure.h index c01d2fc96..d52370757 100644 --- a/ext/libclementine-common/core/closure.h +++ b/ext/libclementine-common/core/closure.h @@ -18,12 +18,14 @@ #ifndef CLOSURE_H #define CLOSURE_H +#include #include #include #include #include #include +#include namespace _detail { @@ -188,7 +190,19 @@ _detail::ClosureBase* NewClosure(QObject* sender, const char* signal, } void DoAfter(QObject* receiver, const char* slot, int msec); -void DoAfter(std::function callback, int msec); +void DoAfter(std::function callback, std::chrono::milliseconds msec); void DoInAMinuteOrSo(QObject* receiver, const char* slot); +template +void DoAfter( + std::function callback, std::chrono::duration duration) { + QTimer* timer = new QTimer; + timer->setSingleShot(true); + NewClosure(timer, SIGNAL(timeout()), callback); + QObject::connect(timer, SIGNAL(timeout()), timer, SLOT(deleteLater())); + std::chrono::milliseconds msec = + std::chrono::duration_cast(duration); + timer->start(msec.count()); +} + #endif // CLOSURE_H diff --git a/ext/libclementine-common/core/logging.cpp b/ext/libclementine-common/core/logging.cpp index acbc0e2f0..ec8faa267 100644 --- a/ext/libclementine-common/core/logging.cpp +++ b/ext/libclementine-common/core/logging.cpp @@ -266,3 +266,17 @@ void DumpStackTrace() { } } // namespace logging + +namespace { + +template +QString print_duration(T duration, const std::string& unit) { + return QString("%1%2").arg(duration.count()).arg(unit.c_str()); +} + +} // namespace + +QDebug operator<<(QDebug dbg, std::chrono::seconds secs) { + dbg.nospace() << print_duration(secs, "s"); + return dbg.space(); +} diff --git a/ext/libclementine-common/core/logging.h b/ext/libclementine-common/core/logging.h index 8cba187ea..21eebdf3a 100644 --- a/ext/libclementine-common/core/logging.h +++ b/ext/libclementine-common/core/logging.h @@ -21,6 +21,9 @@ #ifndef LOGGING_H #define LOGGING_H +#include +#include + #include #ifdef QT_NO_DEBUG_STREAM @@ -61,4 +64,6 @@ void GLog(const char* domain, int level, const char* message, void* user_data); extern const char* kDefaultLogLevels; } +QDebug operator<<(QDebug debug, std::chrono::seconds secs); + #endif // LOGGING_H diff --git a/src/internet/amazon/amazonclouddrive.cpp b/src/internet/amazon/amazonclouddrive.cpp index a373799a5..257d6a539 100644 --- a/src/internet/amazon/amazonclouddrive.cpp +++ b/src/internet/amazon/amazonclouddrive.cpp @@ -17,6 +17,7 @@ #include "internet/amazon/amazonclouddrive.h" +#include #include #include @@ -37,6 +38,7 @@ #include "library/librarybackend.h" #include "ui/settingsdialog.h" +using std::chrono::seconds; using std::placeholders::_1; const char* AmazonCloudDrive::kServiceName = "Amazon Cloud Drive"; @@ -197,16 +199,16 @@ void AmazonCloudDrive::MonitorReply(QNetworkReply* reply, reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if (code >= 500) { // Retry with exponential backoff. int max_delay_s = std::pow(std::min(retries + 1, 8), 2); - int delay_s = qrand() % max_delay_s; + seconds delay(qrand() % max_delay_s); qLog(Debug) << "Request failed with code:" << code << "- retrying after" - << delay_s << "seconds"; + << delay << "seconds"; DoAfter([=]() { if (post_data.isEmpty()) { Get(reply->request(), done, retries + 1); } else { Post(reply->request(), post_data, done, retries + 1); } - }, delay_s * kMsecPerSec); + }, delay); } else { // Request failed permanently. done(reply);