Experiment with typesafe time units

This commit is contained in:
John Maguire 2015-07-20 14:35:13 +01:00
parent 1a968b3a64
commit b2a532be62
5 changed files with 39 additions and 14 deletions

View File

@ -17,8 +17,6 @@
#include "closure.h"
#include <QTimer>
#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<void()> 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);
}

View File

@ -18,12 +18,14 @@
#ifndef CLOSURE_H
#define CLOSURE_H
#include <chrono>
#include <functional>
#include <memory>
#include <QMetaMethod>
#include <QObject>
#include <QSharedPointer>
#include <QTimer>
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<void()> callback, int msec);
void DoAfter(std::function<void()> callback, std::chrono::milliseconds msec);
void DoInAMinuteOrSo(QObject* receiver, const char* slot);
template <typename R, typename P>
void DoAfter(
std::function<void()> callback, std::chrono::duration<R, P> 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<std::chrono::milliseconds>(duration);
timer->start(msec.count());
}
#endif // CLOSURE_H

View File

@ -266,3 +266,17 @@ void DumpStackTrace() {
}
} // namespace logging
namespace {
template<typename T>
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();
}

View File

@ -21,6 +21,9 @@
#ifndef LOGGING_H
#define LOGGING_H
#include <chrono>
#include <string>
#include <QDebug>
#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

View File

@ -17,6 +17,7 @@
#include "internet/amazon/amazonclouddrive.h"
#include <chrono>
#include <cmath>
#include <QtGlobal>
@ -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);