Commit e7d903e3 authored by Ingo Klöcker's avatar Ingo Klöcker
Browse files

Unify retrying to connect to the GnuPG agent

Retry up to 10 times with increasing delay starting as 125 ms and
capped at 1000 ms.

GnuPG-bug-id: 5775
parent 2089a57d
......@@ -20,6 +20,16 @@
using namespace Kleo;
using namespace GpgME;
using namespace std::chrono_literals;
static const auto initialRetryDelay = 125ms;
static const auto maxRetryDelay = 1000ms;
static const auto maxConnectionAttempts = 10;
DeviceInfoWatcher::Worker::Worker()
: mRetryDelay{initialRetryDelay}
{
}
DeviceInfoWatcher::Worker::~Worker()
{
......@@ -39,20 +49,21 @@ void DeviceInfoWatcher::Worker::start()
}
}
// try to connect to the agent for at most ~12.8 seconds with increasing delay between retries
static const int MaxRetryDelay = 100 * 64;
static const char *command = "SCD DEVINFO --watch";
std::unique_ptr<AssuanTransaction> t(new StatusConsumerAssuanTransaction(this));
const Error err = mContext->startAssuanTransaction(command, std::move(t));
if (!err) {
qCDebug(KLEOPATRA_LOG) << "DeviceInfoWatcher::Worker::start: Assuan transaction for" << command << "started";
mRetryDelay = initialRetryDelay;
mFailedConnectionAttempts = 0;
QMetaObject::invokeMethod(this, "poll", Qt::QueuedConnection);
return;
} else if (err.code() == GPG_ERR_ASS_CONNECT_FAILED) {
if (mRetryDelay <= MaxRetryDelay) {
qCInfo(KLEOPATRA_LOG) << "DeviceInfoWatcher::Worker::start: Connecting to the agent failed. Retrying in" << mRetryDelay << "ms";
QThread::msleep(mRetryDelay);
mRetryDelay *= 2;
mFailedConnectionAttempts++;
if (mFailedConnectionAttempts < maxConnectionAttempts) {
qCInfo(KLEOPATRA_LOG) << "DeviceInfoWatcher::Worker::start: Connecting to the agent failed. Retrying in" << mRetryDelay.count() << "ms";
QThread::msleep(mRetryDelay.count());
mRetryDelay = std::min(mRetryDelay * 2, maxRetryDelay);
QMetaObject::invokeMethod(this, "start", Qt::QueuedConnection);
return;
}
......
......@@ -16,6 +16,7 @@
#include <QThread>
#include <chrono>
#include <memory>
namespace Kleo
......@@ -26,6 +27,7 @@ class DeviceInfoWatcher::Worker : public QObject, public GpgME::StatusConsumer
Q_OBJECT
public:
Worker();
~Worker() override;
public Q_SLOTS:
......@@ -40,7 +42,8 @@ private:
void status(const char *status, const char *details) override;
private:
int mRetryDelay = 100;
std::chrono::milliseconds mRetryDelay;
int mFailedConnectionAttempts = 0;
std::unique_ptr<GpgME::Context> mContext;
};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment