Allow configuring long-polling timeout
This commit is contained in:
parent
2b58266d8b
commit
fada3c98dd
|
@ -83,6 +83,7 @@ SyncthingConnection::SyncthingConnection(
|
|||
, m_lastDiskEventId(0)
|
||||
, m_autoReconnectTries(0)
|
||||
, m_requestTimeout(SyncthingConnectionSettings::defaultRequestTimeout)
|
||||
, m_longPollingTimeout(SyncthingConnectionSettings::defaultLongPollingTimeout)
|
||||
, m_totalIncomingTraffic(unknownTraffic)
|
||||
, m_totalOutgoingTraffic(unknownTraffic)
|
||||
, m_totalIncomingRate(0.0)
|
||||
|
@ -857,6 +858,7 @@ bool SyncthingConnection::applySettings(SyncthingConnectionSettings &connectionS
|
|||
setErrorsPollInterval(connectionSettings.errorsPollInterval);
|
||||
setAutoReconnectInterval(connectionSettings.reconnectInterval);
|
||||
setRequestTimeout(connectionSettings.requestTimeout);
|
||||
setLongPollingTimeout(connectionSettings.longPollingTimeout);
|
||||
setStatusComputionFlags(connectionSettings.statusComputionFlags);
|
||||
|
||||
return reconnectRequired;
|
||||
|
|
|
@ -73,6 +73,7 @@ class LIB_SYNCTHING_CONNECTOR_EXPORT SyncthingConnection : public QObject {
|
|||
Q_PROPERTY(int devStatsPollInterval READ devStatsPollInterval WRITE setDevStatsPollInterval)
|
||||
Q_PROPERTY(bool recordFileChanges READ recordFileChanges WRITE setRecordFileChanges)
|
||||
Q_PROPERTY(int requestTimeout READ requestTimeout WRITE setRequestTimeout)
|
||||
Q_PROPERTY(int longPollingTimeout READ longPollingTimeout WRITE setLongPollingTimeout)
|
||||
Q_PROPERTY(QString myId READ myId NOTIFY myIdChanged)
|
||||
Q_PROPERTY(QString tilde READ tilde NOTIFY tildeChanged)
|
||||
Q_PROPERTY(QString pathSeparator READ pathSeparator NOTIFY tildeChanged)
|
||||
|
@ -141,6 +142,8 @@ public:
|
|||
void setRecordFileChanges(bool recordFileChanges);
|
||||
int requestTimeout() const;
|
||||
void setRequestTimeout(int requestTimeout);
|
||||
int longPollingTimeout() const;
|
||||
void setLongPollingTimeout(int longPollingTimeout);
|
||||
|
||||
// getter for information retrieved from Syncthing
|
||||
const QString &configDir() const;
|
||||
|
@ -345,8 +348,8 @@ private:
|
|||
QNetworkReply *reply;
|
||||
QByteArray response;
|
||||
};
|
||||
QNetworkRequest prepareRequest(const QString &path, const QUrlQuery &query, bool rest = true, bool noTimeout = false);
|
||||
QNetworkReply *requestData(const QString &path, const QUrlQuery &query, bool rest = true, bool noTimeout = false);
|
||||
QNetworkRequest prepareRequest(const QString &path, const QUrlQuery &query, bool rest = true, bool longPolling = false);
|
||||
QNetworkReply *requestData(const QString &path, const QUrlQuery &query, bool rest = true, bool longPolling = false);
|
||||
QNetworkReply *postData(const QString &path, const QUrlQuery &query, const QByteArray &data = QByteArray());
|
||||
QNetworkReply *sendData(const QByteArray &verb, const QString &path, const QUrlQuery &query, const QByteArray &data = QByteArray());
|
||||
Reply prepareReply(bool readData = true, bool handleAborting = true);
|
||||
|
@ -382,6 +385,7 @@ private:
|
|||
QTimer m_autoReconnectTimer;
|
||||
unsigned int m_autoReconnectTries;
|
||||
int m_requestTimeout;
|
||||
int m_longPollingTimeout;
|
||||
QString m_configDir;
|
||||
QString m_myId;
|
||||
QString m_tilde;
|
||||
|
@ -739,6 +743,25 @@ inline void SyncthingConnection::setRequestTimeout(int requestTimeout)
|
|||
m_requestTimeout = requestTimeout;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the transfer timeout for long polling requests (event APIs) in milliseconds.
|
||||
* \sa QNetworkRequest::transferTimeout()
|
||||
*/
|
||||
inline int SyncthingConnection::longPollingTimeout() const
|
||||
{
|
||||
return m_longPollingTimeout;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the transfer timeout for long polling requests (event APIs) in milliseconds.
|
||||
* \remarks Existing requests are not affected. Only effective when compiled against Qt 5.15 or higher.
|
||||
* \sa QNetworkRequest::setTransferTimeout()
|
||||
*/
|
||||
inline void SyncthingConnection::setLongPollingTimeout(int longPollingTimeout)
|
||||
{
|
||||
m_longPollingTimeout = longPollingTimeout;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns what information is considered to compute the overall status returned by status().
|
||||
*/
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace Data {
|
|||
/*!
|
||||
* \brief Prepares a request for the specified \a path and \a query.
|
||||
*/
|
||||
QNetworkRequest SyncthingConnection::prepareRequest(const QString &path, const QUrlQuery &query, bool rest, bool noTimeout)
|
||||
QNetworkRequest SyncthingConnection::prepareRequest(const QString &path, const QUrlQuery &query, bool rest, bool longPolling)
|
||||
{
|
||||
QUrl url(m_syncthingUrl);
|
||||
url.setPath(rest ? (url.path() % QStringLiteral("/rest/") % path) : (url.path() + path));
|
||||
|
@ -49,7 +49,8 @@ QNetworkRequest SyncthingConnection::prepareRequest(const QString &path, const Q
|
|||
request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy);
|
||||
#endif
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
||||
request.setTransferTimeout(noTimeout ? 0 : m_requestTimeout);
|
||||
// give it a few seconds more time than the actual long polling interval set via the timeout query parameter
|
||||
request.setTransferTimeout(longPolling ? (m_longPollingTimeout ? m_longPollingTimeout + 5000 : 0) : m_requestTimeout);
|
||||
#endif
|
||||
return request;
|
||||
}
|
||||
|
@ -57,16 +58,17 @@ QNetworkRequest SyncthingConnection::prepareRequest(const QString &path, const Q
|
|||
/*!
|
||||
* \brief Requests asynchronously data using the rest API.
|
||||
*/
|
||||
QNetworkReply *SyncthingConnection::requestData(const QString &path, const QUrlQuery &query, bool rest, bool noTimeout)
|
||||
QNetworkReply *SyncthingConnection::requestData(const QString &path, const QUrlQuery &query, bool rest, bool longPolling)
|
||||
{
|
||||
#ifndef LIB_SYNCTHING_CONNECTOR_CONNECTION_MOCKED
|
||||
auto *const reply = networkAccessManager().get(prepareRequest(path, query, rest, noTimeout));
|
||||
auto *const reply = networkAccessManager().get(prepareRequest(path, query, rest, longPolling));
|
||||
QObject::connect(reply, &QNetworkReply::sslErrors, this, &SyncthingConnection::handleSslErrors);
|
||||
if (loggingFlags() & SyncthingConnectionLoggingFlags::ApiCalls) {
|
||||
cerr << Phrases::Info << "Querying API: GET " << reply->url().toString().toStdString() << Phrases::EndFlush;
|
||||
}
|
||||
return reply;
|
||||
#else
|
||||
Q_UNUSED(longPolling)
|
||||
return MockedReply::forRequest(QStringLiteral("GET"), path, query, rest);
|
||||
#endif
|
||||
}
|
||||
|
@ -1709,6 +1711,8 @@ void SyncthingConnection::requestEvents()
|
|||
// force to return immediately after the first call
|
||||
if (!m_hasEvents) {
|
||||
query.addQueryItem(QStringLiteral("timeout"), QStringLiteral("0"));
|
||||
} else if (m_longPollingTimeout) {
|
||||
query.addQueryItem(QStringLiteral("timeout"), QString::number(m_longPollingTimeout / 1000));
|
||||
}
|
||||
QObject::connect(m_eventsReply = requestData(QStringLiteral("events"), query, true, m_hasEvents), &QNetworkReply::finished, this,
|
||||
&SyncthingConnection::readEvents);
|
||||
|
@ -2315,6 +2319,8 @@ void SyncthingConnection::requestDiskEvents(int limit)
|
|||
// force to return immediately after the first call
|
||||
if (!m_hasDiskEvents) {
|
||||
query.addQueryItem(QStringLiteral("timeout"), QStringLiteral("0"));
|
||||
} else if (m_longPollingTimeout) {
|
||||
query.addQueryItem(QStringLiteral("timeout"), QString::number(m_longPollingTimeout / 1000));
|
||||
}
|
||||
QObject::connect(m_diskEventsReply = requestData(QStringLiteral("events/disk"), query, true, m_hasDiskEvents), &QNetworkReply::finished, this,
|
||||
&SyncthingConnection::readDiskEvents);
|
||||
|
|
|
@ -44,6 +44,7 @@ struct LIB_SYNCTHING_CONNECTOR_EXPORT SyncthingConnectionSettings {
|
|||
int errorsPollInterval = defaultErrorsPollInterval;
|
||||
int reconnectInterval = defaultReconnectInterval;
|
||||
int requestTimeout = defaultRequestTimeout;
|
||||
int longPollingTimeout = defaultLongPollingTimeout;
|
||||
QString httpsCertPath;
|
||||
QList<QSslError> expectedSslErrors;
|
||||
SyncthingStatusComputionFlags statusComputionFlags = SyncthingStatusComputionFlags::Default;
|
||||
|
@ -55,6 +56,7 @@ struct LIB_SYNCTHING_CONNECTOR_EXPORT SyncthingConnectionSettings {
|
|||
static constexpr int defaultErrorsPollInterval = 30000;
|
||||
static constexpr int defaultReconnectInterval = 30000;
|
||||
static constexpr int defaultRequestTimeout = 0;
|
||||
static constexpr int defaultLongPollingTimeout = 0;
|
||||
};
|
||||
} // namespace Data
|
||||
|
||||
|
|
|
@ -305,7 +305,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="18" column="0">
|
||||
<item row="19" column="0">
|
||||
<widget class="QLabel" name="pollLabel">
|
||||
<property name="text">
|
||||
<string>Poll interval</string>
|
||||
|
@ -315,7 +315,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="18" column="1">
|
||||
<item row="19" column="1">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="horizontalSpacing">
|
||||
<number>10</number>
|
||||
|
@ -455,7 +455,7 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="19" column="1">
|
||||
<item row="20" column="1">
|
||||
<widget class="QCheckBox" name="autoConnectCheckBox">
|
||||
<property name="toolTip">
|
||||
<string>Whether to connect automatically on startup. This setting might be overruled by systemd and launcher settings.</string>
|
||||
|
@ -465,7 +465,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="20" column="0">
|
||||
<item row="21" column="0">
|
||||
<widget class="QLabel" name="overallStatusLabel">
|
||||
<property name="text">
|
||||
<string>Overall status</string>
|
||||
|
@ -475,7 +475,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="20" column="1">
|
||||
<item row="21" column="1">
|
||||
<layout class="QVBoxLayout" name="statusComputionFlagsVerticalLayout">
|
||||
<property name="spacing">
|
||||
<number>2</number>
|
||||
|
@ -520,21 +520,21 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="21" column="0">
|
||||
<item row="22" column="0">
|
||||
<widget class="QLabel" name="statusTextLabel">
|
||||
<property name="text">
|
||||
<string>Current status</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="21" column="1">
|
||||
<item row="22" column="1">
|
||||
<widget class="QLabel" name="statusLabel">
|
||||
<property name="text">
|
||||
<string>disconnected</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="24" column="1">
|
||||
<item row="25" column="1">
|
||||
<widget class="QPushButton" name="connectPushButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
|
@ -567,6 +567,9 @@
|
|||
</item>
|
||||
<item row="17" column="0">
|
||||
<widget class="QLabel" name="timeoutLabel">
|
||||
<property name="toolTip">
|
||||
<string>The timeout for normal requests to Syncthing's API. Set to zero to enforce no timeout.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Transfer timeout</string>
|
||||
</property>
|
||||
|
@ -614,6 +617,32 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="18" column="0">
|
||||
<widget class="QLabel" name="longPollingLabel">
|
||||
<property name="toolTip">
|
||||
<string>The timeout for long-polling requests to Syncthing's event API. Set to zero to use Syncthing's default timeout and no timeout being enforced from Syncthing Tray's side.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Long polling int.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="18" column="1">
|
||||
<widget class="QSpinBox" name="longPollingSpinBox">
|
||||
<property name="specialValueText">
|
||||
<string>Syncthing's default with no timeout</string>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> ms</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000000000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>60000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
|
|
|
@ -310,6 +310,8 @@ bool restore()
|
|||
connectionSettings->reconnectInterval
|
||||
= settings.value(QStringLiteral("reconnectInterval"), connectionSettings->reconnectInterval).toInt();
|
||||
connectionSettings->requestTimeout = settings.value(QStringLiteral("requestTimeout"), connectionSettings->requestTimeout).toInt();
|
||||
connectionSettings->longPollingTimeout
|
||||
= settings.value(QStringLiteral("longPollingTimeout"), connectionSettings->longPollingTimeout).toInt();
|
||||
connectionSettings->autoConnect = settings.value(QStringLiteral("autoConnect"), connectionSettings->autoConnect).toBool();
|
||||
const auto statusComputionFlags = settings.value(QStringLiteral("statusComputionFlags"),
|
||||
QVariant::fromValue(static_cast<UnderlyingFlagType>(connectionSettings->statusComputionFlags)));
|
||||
|
@ -461,6 +463,7 @@ bool save()
|
|||
settings.setValue(QStringLiteral("errorsPollInterval"), connectionSettings->errorsPollInterval);
|
||||
settings.setValue(QStringLiteral("reconnectInterval"), connectionSettings->reconnectInterval);
|
||||
settings.setValue(QStringLiteral("requestTimeout"), connectionSettings->requestTimeout);
|
||||
settings.setValue(QStringLiteral("longPollingTimeout"), connectionSettings->longPollingTimeout);
|
||||
settings.setValue(QStringLiteral("autoConnect"), connectionSettings->autoConnect);
|
||||
settings.setValue(QStringLiteral("statusComputionFlags"),
|
||||
QVariant::fromValue(static_cast<std::underlying_type_t<Data::SyncthingStatusComputionFlags>>(connectionSettings->statusComputionFlags)));
|
||||
|
|
|
@ -214,6 +214,7 @@ bool ConnectionOptionPage::showConnectionSettings(int index)
|
|||
ui()->apiKeyLineEdit->setText(connectionSettings.apiKey);
|
||||
ui()->certPathSelection->lineEdit()->setText(connectionSettings.httpsCertPath);
|
||||
ui()->timeoutSpinBox->setValue(connectionSettings.requestTimeout);
|
||||
ui()->longPollingSpinBox->setValue(connectionSettings.longPollingTimeout);
|
||||
ui()->pollTrafficSpinBox->setValue(connectionSettings.trafficPollInterval);
|
||||
ui()->pollDevStatsSpinBox->setValue(connectionSettings.devStatsPollInterval);
|
||||
ui()->pollErrorsSpinBox->setValue(connectionSettings.errorsPollInterval);
|
||||
|
@ -240,6 +241,7 @@ bool ConnectionOptionPage::cacheCurrentSettings(bool applying)
|
|||
connectionSettings.expectedSslErrors.clear();
|
||||
connectionSettings.httpsCertPath = ui()->certPathSelection->lineEdit()->text();
|
||||
connectionSettings.requestTimeout = ui()->timeoutSpinBox->value();
|
||||
connectionSettings.longPollingTimeout = ui()->longPollingSpinBox->value();
|
||||
connectionSettings.trafficPollInterval = ui()->pollTrafficSpinBox->value();
|
||||
connectionSettings.devStatsPollInterval = ui()->pollDevStatsSpinBox->value();
|
||||
connectionSettings.errorsPollInterval = ui()->pollErrorsSpinBox->value();
|
||||
|
@ -364,9 +366,9 @@ void ConnectionOptionPage::toggleAdvancedSettings(bool show)
|
|||
return;
|
||||
}
|
||||
for (auto *const widget : std::initializer_list<QWidget *>{ ui()->authLabel, ui()->authCheckBox, ui()->userNameLabel, ui()->userNameLineEdit,
|
||||
ui()->passwordLabel, ui()->passwordLineEdit, ui()->timeoutLabel, ui()->timeoutSpinBox, ui()->pollLabel, ui()->pollDevStatsLabel,
|
||||
ui()->pollDevStatsSpinBox, ui()->pollErrorsLabel, ui()->pollErrorsSpinBox, ui()->pollTrafficLabel, ui()->pollTrafficSpinBox,
|
||||
ui()->reconnectLabel, ui()->reconnectSpinBox }) {
|
||||
ui()->passwordLabel, ui()->passwordLineEdit, ui()->timeoutLabel, ui()->timeoutSpinBox, ui()->longPollingLabel, ui()->longPollingSpinBox,
|
||||
ui()->pollLabel, ui()->pollDevStatsLabel, ui()->pollDevStatsSpinBox, ui()->pollErrorsLabel, ui()->pollErrorsSpinBox,
|
||||
ui()->pollTrafficLabel, ui()->pollTrafficSpinBox, ui()->reconnectLabel, ui()->reconnectSpinBox }) {
|
||||
widget->setVisible(show);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue