Allow auto-reconnect

This commit is contained in:
Martchus 2016-10-07 15:11:25 +02:00
parent 39f6424b3a
commit 138a7cc382
7 changed files with 96 additions and 1 deletions

View File

@ -54,6 +54,7 @@ SyncthingConnection::SyncthingConnection(const QString &syncthingUrl, const QByt
m_lastEventId(0), m_lastEventId(0),
m_trafficPollInterval(2000), m_trafficPollInterval(2000),
m_devStatsPollInterval(60000), m_devStatsPollInterval(60000),
m_reconnectTimer(),
m_totalIncomingTraffic(0), m_totalIncomingTraffic(0),
m_totalOutgoingTraffic(0), m_totalOutgoingTraffic(0),
m_totalIncomingRate(0), m_totalIncomingRate(0),
@ -67,7 +68,10 @@ SyncthingConnection::SyncthingConnection(const QString &syncthingUrl, const QByt
m_hasConfig(false), m_hasConfig(false),
m_hasStatus(false), m_hasStatus(false),
m_lastFileDeleted(false) m_lastFileDeleted(false)
{} {
m_reconnectTimer.setTimerType(Qt::VeryCoarseTimer);
QObject::connect(&m_reconnectTimer, &QTimer::timeout, this, static_cast<void(SyncthingConnection::*)(void)>(&SyncthingConnection::connect));
}
/*! /*!
* \brief Destroys the instance. Ongoing requests are aborted. * \brief Destroys the instance. Ongoing requests are aborted.
@ -117,6 +121,7 @@ bool SyncthingConnection::hasOutOfSyncDirs() const
*/ */
void SyncthingConnection::connect() void SyncthingConnection::connect()
{ {
m_reconnectTimer.stop();
if(!isConnected()) { if(!isConnected()) {
m_reconnecting = m_hasConfig = m_hasStatus = false; m_reconnecting = m_hasConfig = m_hasStatus = false;
if(m_apiKey.isEmpty() || m_syncthingUrl.isEmpty()) { if(m_apiKey.isEmpty() || m_syncthingUrl.isEmpty()) {
@ -144,6 +149,7 @@ void SyncthingConnection::disconnect()
*/ */
void SyncthingConnection::reconnect() void SyncthingConnection::reconnect()
{ {
m_reconnectTimer.stop();
if(isConnected()) { if(isConnected()) {
m_reconnecting = true; m_reconnecting = true;
m_hasConfig = m_hasStatus = false; m_hasConfig = m_hasStatus = false;
@ -622,6 +628,7 @@ void SyncthingConnection::applySettings(SyncthingConnectionSettings &connectionS
} }
setTrafficPollInterval(connectionSettings.trafficPollInterval); setTrafficPollInterval(connectionSettings.trafficPollInterval);
setDevStatsPollInterval(connectionSettings.devStatsPollInterval); setDevStatsPollInterval(connectionSettings.devStatsPollInterval);
setReconnectInterval(connectionSettings.reconnectInterval);
if(connectionSettings.expectedSslErrors.isEmpty()) { if(connectionSettings.expectedSslErrors.isEmpty()) {
loadSelfSignedCertificate(); loadSelfSignedCertificate();
connectionSettings.expectedSslErrors = expectedSslErrors(); connectionSettings.expectedSslErrors = expectedSslErrors();
@ -661,6 +668,9 @@ void SyncthingConnection::readConfig()
default: default:
emit error(tr("Unable to request Syncthing config: ") + reply->errorString()); emit error(tr("Unable to request Syncthing config: ") + reply->errorString());
setStatus(SyncthingStatus::Disconnected); setStatus(SyncthingStatus::Disconnected);
if(m_reconnectTimer.interval()) {
m_reconnectTimer.start();
}
} }
} }
@ -1046,6 +1056,9 @@ void SyncthingConnection::readEvents()
} else { } else {
emit error(tr("Unable to parse Syncthing events: ") + jsonError.errorString()); emit error(tr("Unable to parse Syncthing events: ") + jsonError.errorString());
setStatus(SyncthingStatus::Disconnected); setStatus(SyncthingStatus::Disconnected);
if(m_reconnectTimer.interval()) {
m_reconnectTimer.start();
}
return; return;
} }
break; break;
@ -1065,6 +1078,9 @@ void SyncthingConnection::readEvents()
default: default:
emit error(tr("Unable to request Syncthing events: ") + reply->errorString()); emit error(tr("Unable to request Syncthing events: ") + reply->errorString());
setStatus(SyncthingStatus::Disconnected); setStatus(SyncthingStatus::Disconnected);
if(m_reconnectTimer.interval()) {
m_reconnectTimer.start();
}
return; return;
} }

View File

@ -7,6 +7,7 @@
#include <QObject> #include <QObject>
#include <QList> #include <QList>
#include <QSslError> #include <QSslError>
#include <QTimer>
#include <functional> #include <functional>
#include <vector> #include <vector>
@ -83,6 +84,8 @@ public:
void setTrafficPollInterval(int trafficPollInterval); void setTrafficPollInterval(int trafficPollInterval);
int devStatsPollInterval() const; int devStatsPollInterval() const;
void setDevStatsPollInterval(int devStatsPollInterval); void setDevStatsPollInterval(int devStatsPollInterval);
int reconnectInterval() const;
void setReconnectInterval(int reconnectInterval);
const QString &configDir() const; const QString &configDir() const;
const QString &myId() const; const QString &myId() const;
int totalIncomingTraffic() const; int totalIncomingTraffic() const;
@ -186,6 +189,7 @@ private:
int m_lastEventId; int m_lastEventId;
int m_trafficPollInterval; int m_trafficPollInterval;
int m_devStatsPollInterval; int m_devStatsPollInterval;
QTimer m_reconnectTimer;
QString m_configDir; QString m_configDir;
QString m_myId; QString m_myId;
int m_totalIncomingTraffic; int m_totalIncomingTraffic;
@ -327,6 +331,27 @@ inline void SyncthingConnection::setDevStatsPollInterval(int devStatsPollInterva
m_devStatsPollInterval = devStatsPollInterval; m_devStatsPollInterval = devStatsPollInterval;
} }
/*!
* \brief Returns the reconnect interval in milliseconds.
* \remarks Default value is 0 which indicates disabled auto-reconnect.
*/
inline int SyncthingConnection::reconnectInterval() const
{
return m_reconnectTimer.interval();
}
/*!
* \brief Sets the reconnect interval in milliseconds.
* \remarks Default value is 0 which indicates disabled auto-reconnect.
*/
inline void SyncthingConnection::setReconnectInterval(int reconnectInterval)
{
if(!reconnectInterval) {
m_reconnectTimer.stop();
}
m_reconnectTimer.setInterval(reconnectInterval);
}
/*! /*!
* \brief Returns the Syncthing home/configuration directory. * \brief Returns the Syncthing home/configuration directory.
*/ */

View File

@ -18,6 +18,7 @@ struct LIB_SYNCTHING_CONNECTOR_EXPORT SyncthingConnectionSettings {
QByteArray apiKey; QByteArray apiKey;
int trafficPollInterval = 2000; int trafficPollInterval = 2000;
int devStatsPollInterval = 60000; int devStatsPollInterval = 60000;
int reconnectInterval = 0;
QString httpsCertPath; QString httpsCertPath;
QList<QSslError> expectedSslErrors; QList<QSslError> expectedSslErrors;
bool loadHttpsCert(); bool loadHttpsCert();

View File

@ -167,6 +167,7 @@ void restore()
connectionSettings->apiKey = settings.value(QStringLiteral("apiKey")).toByteArray(); connectionSettings->apiKey = settings.value(QStringLiteral("apiKey")).toByteArray();
connectionSettings->trafficPollInterval = settings.value(QStringLiteral("trafficPollInterval"), connectionSettings->trafficPollInterval).toInt(); connectionSettings->trafficPollInterval = settings.value(QStringLiteral("trafficPollInterval"), connectionSettings->trafficPollInterval).toInt();
connectionSettings->devStatsPollInterval = settings.value(QStringLiteral("devStatsPollInterval"), connectionSettings->devStatsPollInterval).toInt(); connectionSettings->devStatsPollInterval = settings.value(QStringLiteral("devStatsPollInterval"), connectionSettings->devStatsPollInterval).toInt();
connectionSettings->reconnectInterval = settings.value(QStringLiteral("reconnectInterval"), connectionSettings->reconnectInterval).toInt();
connectionSettings->httpsCertPath = settings.value(QStringLiteral("httpsCertPath")).toString(); connectionSettings->httpsCertPath = settings.value(QStringLiteral("httpsCertPath")).toString();
if(!connectionSettings->loadHttpsCert()) { if(!connectionSettings->loadHttpsCert()) {
QMessageBox::critical(nullptr, QCoreApplication::applicationName(), QCoreApplication::translate("Settings::restore", "Unable to load certificate \"%1\" when restoring settings.").arg(connectionSettings->httpsCertPath)); QMessageBox::critical(nullptr, QCoreApplication::applicationName(), QCoreApplication::translate("Settings::restore", "Unable to load certificate \"%1\" when restoring settings.").arg(connectionSettings->httpsCertPath));
@ -224,6 +225,7 @@ void save()
settings.setValue(QStringLiteral("apiKey"), connectionSettings->apiKey); settings.setValue(QStringLiteral("apiKey"), connectionSettings->apiKey);
settings.setValue(QStringLiteral("trafficPollInterval"), connectionSettings->trafficPollInterval); settings.setValue(QStringLiteral("trafficPollInterval"), connectionSettings->trafficPollInterval);
settings.setValue(QStringLiteral("devStatsPollInterval"), connectionSettings->devStatsPollInterval); settings.setValue(QStringLiteral("devStatsPollInterval"), connectionSettings->devStatsPollInterval);
settings.setValue(QStringLiteral("reconnectInterval"), connectionSettings->reconnectInterval);
settings.setValue(QStringLiteral("httpsCertPath"), connectionSettings->httpsCertPath); settings.setValue(QStringLiteral("httpsCertPath"), connectionSettings->httpsCertPath);
} }
settings.endArray(); settings.endArray();

View File

@ -295,6 +295,12 @@
</item> </item>
<item> <item>
<widget class="QSpinBox" name="pollTrafficSpinBox"> <widget class="QSpinBox" name="pollTrafficSpinBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="suffix"> <property name="suffix">
<string> ms</string> <string> ms</string>
</property> </property>
@ -322,6 +328,12 @@
</item> </item>
<item> <item>
<widget class="QSpinBox" name="pollDevStatsSpinBox"> <widget class="QSpinBox" name="pollDevStatsSpinBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="suffix"> <property name="suffix">
<string> ms</string> <string> ms</string>
</property> </property>
@ -333,6 +345,39 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="reconnectLabel">
<property name="text">
<string>Reconnect</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="reconnectSpinBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="specialValueText">
<string>no</string>
</property>
<property name="suffix">
<string> ms</string>
</property>
<property name="maximum">
<number>999999999</number>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
</layout> </layout>

View File

@ -118,6 +118,7 @@ bool ConnectionOptionPage::showConnectionSettings(int index)
ui()->certPathSelection->lineEdit()->setText(connectionSettings.httpsCertPath); ui()->certPathSelection->lineEdit()->setText(connectionSettings.httpsCertPath);
ui()->pollTrafficSpinBox->setValue(connectionSettings.trafficPollInterval); ui()->pollTrafficSpinBox->setValue(connectionSettings.trafficPollInterval);
ui()->pollDevStatsSpinBox->setValue(connectionSettings.devStatsPollInterval); ui()->pollDevStatsSpinBox->setValue(connectionSettings.devStatsPollInterval);
ui()->reconnectSpinBox->setValue(connectionSettings.reconnectInterval);
m_currentIndex = index; m_currentIndex = index;
} else { } else {
ui()->selectionComboBox->setCurrentIndex(m_currentIndex); ui()->selectionComboBox->setCurrentIndex(m_currentIndex);
@ -142,6 +143,7 @@ bool ConnectionOptionPage::cacheCurrentSettings(bool applying)
connectionSettings.httpsCertPath = ui()->certPathSelection->lineEdit()->text(); connectionSettings.httpsCertPath = ui()->certPathSelection->lineEdit()->text();
connectionSettings.trafficPollInterval = ui()->pollTrafficSpinBox->value(); connectionSettings.trafficPollInterval = ui()->pollTrafficSpinBox->value();
connectionSettings.devStatsPollInterval = ui()->pollDevStatsSpinBox->value(); connectionSettings.devStatsPollInterval = ui()->pollDevStatsSpinBox->value();
connectionSettings.reconnectInterval = ui()->reconnectSpinBox->value();
if(!connectionSettings.loadHttpsCert()) { if(!connectionSettings.loadHttpsCert()) {
const QString errorMessage = QCoreApplication::translate("QtGui::ConnectionOptionPage", "Unable to load specified certificate \"%1\".").arg(connectionSettings.httpsCertPath); const QString errorMessage = QCoreApplication::translate("QtGui::ConnectionOptionPage", "Unable to load specified certificate \"%1\".").arg(connectionSettings.httpsCertPath);
if(!applying) { if(!applying) {

View File

@ -294,6 +294,8 @@ void TrayWidget::handleStatusChanged(SyncthingStatus status)
m_ui->statusPushButton->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-start"), QIcon(QStringLiteral(":/icons/hicolor/scalable/actions/media-playback-resume.svg")))); m_ui->statusPushButton->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-start"), QIcon(QStringLiteral(":/icons/hicolor/scalable/actions/media-playback-resume.svg"))));
m_ui->statusPushButton->setHidden(false); m_ui->statusPushButton->setHidden(false);
break; break;
default:
;
} }
} }
@ -404,6 +406,8 @@ void TrayWidget::changeStatus()
case SyncthingStatus::Paused: case SyncthingStatus::Paused:
m_connection.resumeAllDevs(); m_connection.resumeAllDevs();
break; break;
default:
;
} }
} }