From cc7d034fa67196ad4950d3785aff64e4c5765855 Mon Sep 17 00:00:00 2001
From: Alexey Andreyev <aa13q@ya.ru>
Date: Wed, 30 Jan 2019 19:30:07 +0300
Subject: Connection: infinite sync loop logic by default

---
 lib/connection.cpp | 13 ++++++++++++-
 lib/connection.h   |  3 +++
 2 files changed, 15 insertions(+), 1 deletion(-)

(limited to 'lib')

diff --git a/lib/connection.cpp b/lib/connection.cpp
index c582cf94..982145f7 100644
--- a/lib/connection.cpp
+++ b/lib/connection.cpp
@@ -133,6 +133,8 @@ Connection::Connection(const QUrl& server, QObject* parent)
     , d(std::make_unique<Private>(std::make_unique<ConnectionData>(server)))
 {
     d->q = this; // All d initialization should occur before this line
+    // sync loop:
+    connect(this, &Connection::syncDone, this, &Connection::getNewEvents);
 }
 
 Connection::Connection(QObject* parent)
@@ -250,7 +252,7 @@ void Connection::Private::connectWithToken(const QString& user,
                   << "by user" << userId << "from device" << deviceId;
     emit q->stateChanged();
     emit q->connected();
-
+    q->sync(); // initial sync after connection
 }
 
 void Connection::checkAndConnect(const QString& userId,
@@ -406,6 +408,15 @@ void Connection::onSyncSuccess(SyncData &&data, bool fromCache) {
     }
 }
 
+void Connection::getNewEvents()
+{
+    // Borrowed the logic from Quiark's code in Tensor
+    // to cache not too aggressively and not on the first sync.
+    if (++_saveStateCounter % 17 == 2)
+        saveState();
+    sync(30*1000);
+}
+
 void Connection::stopSync()
 {
     if (d->syncJob)
diff --git a/lib/connection.h b/lib/connection.h
index 9e4121f4..dcc77824 100644
--- a/lib/connection.h
+++ b/lib/connection.h
@@ -678,6 +678,7 @@ namespace QMatrixClient
              * Completes loading sync data.
              */
             void onSyncSuccess(SyncData &&data, bool fromCache = false);
+            void getNewEvents();
 
         private:
             class Private;
@@ -702,6 +703,8 @@ namespace QMatrixClient
 
             static room_factory_t _roomFactory;
             static user_factory_t _userFactory;
+
+            int _saveStateCounter = 0;
     };
 }  // namespace QMatrixClient
 Q_DECLARE_METATYPE(QMatrixClient::Connection*)
-- 
cgit v1.2.3


From 22dd5f1e8988b03a691487cdad164a82a36e7f8c Mon Sep 17 00:00:00 2001
From: Alexey Andreyev <aa13q@ya.ru>
Date: Sat, 2 Feb 2019 23:51:20 +0300
Subject: Connection: separated sync loop logic with delay control

Signed-off-by: Alexey Andreyev <aa13q@ya.ru>
---
 lib/connection.cpp | 69 +++++++++++++++++++++++++++++++++++++++++++++++-------
 lib/connection.h   | 30 +++++++++++++++++++++++-
 2 files changed, 90 insertions(+), 9 deletions(-)

(limited to 'lib')

diff --git a/lib/connection.cpp b/lib/connection.cpp
index 982145f7..e7f9e4b2 100644
--- a/lib/connection.cpp
+++ b/lib/connection.cpp
@@ -45,6 +45,7 @@
 #include <QtCore/QRegularExpression>
 #include <QtCore/QMimeDatabase>
 #include <QtCore/QCoreApplication>
+#include <QTimer>
 
 using namespace QMatrixClient;
 
@@ -133,8 +134,6 @@ Connection::Connection(const QUrl& server, QObject* parent)
     , d(std::make_unique<Private>(std::make_unique<ConnectionData>(server)))
 {
     d->q = this; // All d initialization should occur before this line
-    // sync loop:
-    connect(this, &Connection::syncDone, this, &Connection::getNewEvents);
 }
 
 Connection::Connection(QObject* parent)
@@ -232,6 +231,11 @@ void Connection::doConnectToServer(const QString& user, const QString& password,
         });
 }
 
+void Connection::syncLoopIteration()
+{
+    sync(_syncLoopTimeout);
+}
+
 void Connection::connectWithToken(const QString& userId,
                                   const QString& accessToken,
                                   const QString& deviceId)
@@ -252,7 +256,6 @@ void Connection::Private::connectWithToken(const QString& user,
                   << "by user" << userId << "from device" << deviceId;
     emit q->stateChanged();
     emit q->connected();
-    q->sync(); // initial sync after connection
 }
 
 void Connection::checkAndConnect(const QString& userId,
@@ -321,6 +324,15 @@ void Connection::sync(int timeout)
     });
 }
 
+void Connection::syncLoop(int timeout)
+{
+    _syncLoopTimeout = timeout;
+    connect(this, &Connection::syncDone, this, &Connection::getNewEventsOnSyncDone);
+    connect(this, &Connection::syncError, this, &Connection::getNewEventsOnSyncError);
+    _syncLoopElapsedTimer.start();
+    sync(_syncLoopTimeout); // initial sync to start the loop
+}
+
 void Connection::onSyncSuccess(SyncData &&data, bool fromCache) {
     d->data->setLastEvent(data.nextBatch());
     for (auto&& roomData: data.takeRoomData())
@@ -410,11 +422,33 @@ void Connection::onSyncSuccess(SyncData &&data, bool fromCache) {
 
 void Connection::getNewEvents()
 {
-    // Borrowed the logic from Quiark's code in Tensor
-    // to cache not too aggressively and not on the first sync.
-    if (++_saveStateCounter % 17 == 2)
-        saveState();
-    sync(30*1000);
+    int delay = minSyncLoopDelayMs() - _syncLoopElapsedTimer.restart();
+    if (delay<0) {
+        delay = 0;
+    }
+    QTimer::singleShot(delay, this, &Connection::syncLoopIteration);
+}
+
+void Connection::getNewEventsOnSyncDone()
+{
+    if (_prevSyncLoopIterationDone) {
+        _syncLoopAttemptNumber++;
+    } else {
+        _syncLoopAttemptNumber = 0;
+    }
+    emit syncAttemptNumberChanged(_syncLoopAttemptNumber);
+    getNewEvents();
+}
+
+void Connection::getNewEventsOnSyncError()
+{
+    if (_prevSyncLoopIterationDone) {
+        _syncLoopAttemptNumber = 0;
+    } else {
+        _syncLoopAttemptNumber++;
+    }
+    emit syncAttemptNumberChanged(_syncLoopAttemptNumber);
+    getNewEvents();
 }
 
 void Connection::stopSync()
@@ -436,6 +470,15 @@ PostReceiptJob* Connection::postReceipt(Room* room, RoomEvent* event) const
     return callApi<PostReceiptJob>(room->id(), "m.read", event->id());
 }
 
+void Connection::setMinSyncDelayMs(qint64 minSyncDelayMs)
+{
+    if (_minSyncLoopDelayMs == minSyncDelayMs)
+        return;
+
+    _minSyncLoopDelayMs = minSyncDelayMs;
+    emit minSyncDelayMsChanged(_minSyncLoopDelayMs);
+}
+
 JoinRoomJob* Connection::joinRoom(const QString& roomAlias,
                                   const QStringList& serverNames)
 {
@@ -1100,6 +1143,16 @@ user_factory_t Connection::userFactory()
     return _userFactory;
 }
 
+qint64 Connection::minSyncLoopDelayMs() const
+{
+    return _minSyncLoopDelayMs;
+}
+
+uint Connection::syncLoopAttemptNumber() const
+{
+    return _syncLoopAttemptNumber;
+}
+
 room_factory_t Connection::_roomFactory = defaultRoomFactory<>();
 user_factory_t Connection::_userFactory = defaultUserFactory<>();
 
diff --git a/lib/connection.h b/lib/connection.h
index dcc77824..ee7ad243 100644
--- a/lib/connection.h
+++ b/lib/connection.h
@@ -26,6 +26,7 @@
 #include <QtCore/QObject>
 #include <QtCore/QUrl>
 #include <QtCore/QSize>
+#include <QElapsedTimer>
 
 #include <functional>
 #include <memory>
@@ -105,6 +106,8 @@ namespace QMatrixClient
             Q_PROPERTY(QUrl homeserver READ homeserver WRITE setHomeserver NOTIFY homeserverChanged)
             Q_PROPERTY(bool cacheState READ cacheState WRITE setCacheState NOTIFY cacheStateChanged)
             Q_PROPERTY(bool lazyLoading READ lazyLoading WRITE setLazyLoading NOTIFY lazyLoadingChanged)
+            Q_PROPERTY(qint64 minSyncLoopDelayMs READ minSyncLoopDelayMs WRITE setMinSyncDelayMs NOTIFY minSyncDelayMsChanged)
+            Q_PROPERTY(uint syncLoopAttemptNumber READ syncLoopAttemptNumber NOTIFY syncAttemptNumberChanged)
 
         public:
             // Room ids, rather than room pointers, are used in the direct chat
@@ -353,6 +356,11 @@ namespace QMatrixClient
             template <typename T>
             static void setUserType() { setUserFactory(defaultUserFactory<T>()); }
 
+            qint64 minSyncLoopDelayMs() const;
+            void setMinSyncDelayMs(qint64 minSyncLoopDelayMs);
+
+            uint syncLoopAttemptNumber() const;
+
         public slots:
             /** Set the homeserver base URL */
             void setHomeserver(const QUrl& baseUrl);
@@ -371,6 +379,15 @@ namespace QMatrixClient
             void logout();
 
             void sync(int timeout = -1);
+
+            /** Start sync loop with the minSyncLoopDelayMs value
+                where minSyncLoopDelayMs could be changed on the client
+                according to syncDone/syncError signals and
+                the syncLoopAttemptNumber counter.
+                The syncLoopAttemptNumber counter is resetting
+                after non-repeating syncDone/syncError events*/
+            void syncLoop(int timeout = -1);
+
             void stopSync();
             QString nextBatchToken() const;
 
@@ -645,6 +662,8 @@ namespace QMatrixClient
             void cacheStateChanged();
             void lazyLoadingChanged();
             void turnServersChanged(const QJsonObject& servers);
+            void minSyncDelayMsChanged(qint64 minSyncLoopDelayMs);
+            void syncAttemptNumberChanged(uint syncLoopAttemptNumber);
 
         protected:
             /**
@@ -678,7 +697,11 @@ namespace QMatrixClient
              * Completes loading sync data.
              */
             void onSyncSuccess(SyncData &&data, bool fromCache = false);
+
+        protected slots:
             void getNewEvents();
+            void getNewEventsOnSyncDone();
+            void getNewEventsOnSyncError();
 
         private:
             class Private;
@@ -704,7 +727,12 @@ namespace QMatrixClient
             static room_factory_t _roomFactory;
             static user_factory_t _userFactory;
 
-            int _saveStateCounter = 0;
+            QElapsedTimer _syncLoopElapsedTimer;
+            int _syncLoopTimeout = -1;
+            qint64 _minSyncLoopDelayMs = 0;
+            void syncLoopIteration();
+            uint _syncLoopAttemptNumber = 0;
+            bool _prevSyncLoopIterationDone = false;
     };
 }  // namespace QMatrixClient
 Q_DECLARE_METATYPE(QMatrixClient::Connection*)
-- 
cgit v1.2.3


From bf6cd3d29052f9e79fee29c6a6646d95271a196a Mon Sep 17 00:00:00 2001
From: Alexey Andreyev <aa13q@ya.ru>
Date: Mon, 4 Feb 2019 11:58:43 +0300
Subject: Connection: simplified sync loop logic without delays

Signed-off-by: Alexey Andreyev <aa13q@ya.ru>
---
 lib/connection.cpp | 58 +++---------------------------------------------------
 lib/connection.h   | 26 +-----------------------
 2 files changed, 4 insertions(+), 80 deletions(-)

(limited to 'lib')

diff --git a/lib/connection.cpp b/lib/connection.cpp
index e7f9e4b2..a9a8bba3 100644
--- a/lib/connection.cpp
+++ b/lib/connection.cpp
@@ -45,7 +45,6 @@
 #include <QtCore/QRegularExpression>
 #include <QtCore/QMimeDatabase>
 #include <QtCore/QCoreApplication>
-#include <QTimer>
 
 using namespace QMatrixClient;
 
@@ -256,6 +255,7 @@ void Connection::Private::connectWithToken(const QString& user,
                   << "by user" << userId << "from device" << deviceId;
     emit q->stateChanged();
     emit q->connected();
+
 }
 
 void Connection::checkAndConnect(const QString& userId,
@@ -327,10 +327,8 @@ void Connection::sync(int timeout)
 void Connection::syncLoop(int timeout)
 {
     _syncLoopTimeout = timeout;
-    connect(this, &Connection::syncDone, this, &Connection::getNewEventsOnSyncDone);
-    connect(this, &Connection::syncError, this, &Connection::getNewEventsOnSyncError);
-    _syncLoopElapsedTimer.start();
-    sync(_syncLoopTimeout); // initial sync to start the loop
+    connect(this, &Connection::syncDone, this, &Connection::syncLoopIteration);
+    syncLoopIteration(); // initial sync to start the loop
 }
 
 void Connection::onSyncSuccess(SyncData &&data, bool fromCache) {
@@ -420,37 +418,6 @@ void Connection::onSyncSuccess(SyncData &&data, bool fromCache) {
     }
 }
 
-void Connection::getNewEvents()
-{
-    int delay = minSyncLoopDelayMs() - _syncLoopElapsedTimer.restart();
-    if (delay<0) {
-        delay = 0;
-    }
-    QTimer::singleShot(delay, this, &Connection::syncLoopIteration);
-}
-
-void Connection::getNewEventsOnSyncDone()
-{
-    if (_prevSyncLoopIterationDone) {
-        _syncLoopAttemptNumber++;
-    } else {
-        _syncLoopAttemptNumber = 0;
-    }
-    emit syncAttemptNumberChanged(_syncLoopAttemptNumber);
-    getNewEvents();
-}
-
-void Connection::getNewEventsOnSyncError()
-{
-    if (_prevSyncLoopIterationDone) {
-        _syncLoopAttemptNumber = 0;
-    } else {
-        _syncLoopAttemptNumber++;
-    }
-    emit syncAttemptNumberChanged(_syncLoopAttemptNumber);
-    getNewEvents();
-}
-
 void Connection::stopSync()
 {
     if (d->syncJob)
@@ -470,15 +437,6 @@ PostReceiptJob* Connection::postReceipt(Room* room, RoomEvent* event) const
     return callApi<PostReceiptJob>(room->id(), "m.read", event->id());
 }
 
-void Connection::setMinSyncDelayMs(qint64 minSyncDelayMs)
-{
-    if (_minSyncLoopDelayMs == minSyncDelayMs)
-        return;
-
-    _minSyncLoopDelayMs = minSyncDelayMs;
-    emit minSyncDelayMsChanged(_minSyncLoopDelayMs);
-}
-
 JoinRoomJob* Connection::joinRoom(const QString& roomAlias,
                                   const QStringList& serverNames)
 {
@@ -1143,16 +1101,6 @@ user_factory_t Connection::userFactory()
     return _userFactory;
 }
 
-qint64 Connection::minSyncLoopDelayMs() const
-{
-    return _minSyncLoopDelayMs;
-}
-
-uint Connection::syncLoopAttemptNumber() const
-{
-    return _syncLoopAttemptNumber;
-}
-
 room_factory_t Connection::_roomFactory = defaultRoomFactory<>();
 user_factory_t Connection::_userFactory = defaultUserFactory<>();
 
diff --git a/lib/connection.h b/lib/connection.h
index ee7ad243..c9ca3580 100644
--- a/lib/connection.h
+++ b/lib/connection.h
@@ -26,7 +26,6 @@
 #include <QtCore/QObject>
 #include <QtCore/QUrl>
 #include <QtCore/QSize>
-#include <QElapsedTimer>
 
 #include <functional>
 #include <memory>
@@ -106,8 +105,6 @@ namespace QMatrixClient
             Q_PROPERTY(QUrl homeserver READ homeserver WRITE setHomeserver NOTIFY homeserverChanged)
             Q_PROPERTY(bool cacheState READ cacheState WRITE setCacheState NOTIFY cacheStateChanged)
             Q_PROPERTY(bool lazyLoading READ lazyLoading WRITE setLazyLoading NOTIFY lazyLoadingChanged)
-            Q_PROPERTY(qint64 minSyncLoopDelayMs READ minSyncLoopDelayMs WRITE setMinSyncDelayMs NOTIFY minSyncDelayMsChanged)
-            Q_PROPERTY(uint syncLoopAttemptNumber READ syncLoopAttemptNumber NOTIFY syncAttemptNumberChanged)
 
         public:
             // Room ids, rather than room pointers, are used in the direct chat
@@ -356,11 +353,6 @@ namespace QMatrixClient
             template <typename T>
             static void setUserType() { setUserFactory(defaultUserFactory<T>()); }
 
-            qint64 minSyncLoopDelayMs() const;
-            void setMinSyncDelayMs(qint64 minSyncLoopDelayMs);
-
-            uint syncLoopAttemptNumber() const;
-
         public slots:
             /** Set the homeserver base URL */
             void setHomeserver(const QUrl& baseUrl);
@@ -379,13 +371,6 @@ namespace QMatrixClient
             void logout();
 
             void sync(int timeout = -1);
-
-            /** Start sync loop with the minSyncLoopDelayMs value
-                where minSyncLoopDelayMs could be changed on the client
-                according to syncDone/syncError signals and
-                the syncLoopAttemptNumber counter.
-                The syncLoopAttemptNumber counter is resetting
-                after non-repeating syncDone/syncError events*/
             void syncLoop(int timeout = -1);
 
             void stopSync();
@@ -662,8 +647,6 @@ namespace QMatrixClient
             void cacheStateChanged();
             void lazyLoadingChanged();
             void turnServersChanged(const QJsonObject& servers);
-            void minSyncDelayMsChanged(qint64 minSyncLoopDelayMs);
-            void syncAttemptNumberChanged(uint syncLoopAttemptNumber);
 
         protected:
             /**
@@ -699,9 +682,7 @@ namespace QMatrixClient
             void onSyncSuccess(SyncData &&data, bool fromCache = false);
 
         protected slots:
-            void getNewEvents();
-            void getNewEventsOnSyncDone();
-            void getNewEventsOnSyncError();
+            void syncLoopIteration();
 
         private:
             class Private;
@@ -727,12 +708,7 @@ namespace QMatrixClient
             static room_factory_t _roomFactory;
             static user_factory_t _userFactory;
 
-            QElapsedTimer _syncLoopElapsedTimer;
             int _syncLoopTimeout = -1;
-            qint64 _minSyncLoopDelayMs = 0;
-            void syncLoopIteration();
-            uint _syncLoopAttemptNumber = 0;
-            bool _prevSyncLoopIterationDone = false;
     };
 }  // namespace QMatrixClient
 Q_DECLARE_METATYPE(QMatrixClient::Connection*)
-- 
cgit v1.2.3


From 73c836239bfa35713ad76d5e205ce2f2dceffffd Mon Sep 17 00:00:00 2001
From: Alexey Andreyev <aa13q@ya.ru>
Date: Sun, 10 Feb 2019 15:08:08 +0300
Subject: Connection: move syncLoopTimeout to Connection::Private

Signed-off-by: Alexey Andreyev <aa13q@ya.ru>
---
 lib/connection.cpp | 5 +++--
 lib/connection.h   | 2 --
 2 files changed, 3 insertions(+), 4 deletions(-)

(limited to 'lib')

diff --git a/lib/connection.cpp b/lib/connection.cpp
index a9a8bba3..63b0a31d 100644
--- a/lib/connection.cpp
+++ b/lib/connection.cpp
@@ -90,6 +90,7 @@ class Connection::Private
         DirectChatUsersMap directChatUsers;
         std::unordered_map<QString, EventPtr> accountData;
         QString userId;
+        int syncLoopTimeout = -1;
 
         SyncJob* syncJob = nullptr;
 
@@ -232,7 +233,7 @@ void Connection::doConnectToServer(const QString& user, const QString& password,
 
 void Connection::syncLoopIteration()
 {
-    sync(_syncLoopTimeout);
+    sync(d->syncLoopTimeout);
 }
 
 void Connection::connectWithToken(const QString& userId,
@@ -326,7 +327,7 @@ void Connection::sync(int timeout)
 
 void Connection::syncLoop(int timeout)
 {
-    _syncLoopTimeout = timeout;
+    d->syncLoopTimeout = timeout;
     connect(this, &Connection::syncDone, this, &Connection::syncLoopIteration);
     syncLoopIteration(); // initial sync to start the loop
 }
diff --git a/lib/connection.h b/lib/connection.h
index c9ca3580..45b691e1 100644
--- a/lib/connection.h
+++ b/lib/connection.h
@@ -707,8 +707,6 @@ namespace QMatrixClient
 
             static room_factory_t _roomFactory;
             static user_factory_t _userFactory;
-
-            int _syncLoopTimeout = -1;
     };
 }  // namespace QMatrixClient
 Q_DECLARE_METATYPE(QMatrixClient::Connection*)
-- 
cgit v1.2.3