From e58739de00bb10b0377382ded45d650bf411501b Mon Sep 17 00:00:00 2001 From: Jocelyn Turcotte Date: Thu, 28 Apr 2016 22:43:53 +0200 Subject: [PATCH] [osx] Fix missing overlay icons on client startup Since the statuses are cached and that we can't invalidate the cache, sending NOP would need to be overwritten by the default OK status once the client successfully connected. But instead of remembering which files we NOPed, rather wait until we are ready to sync before sending the REGISTER_PATH message to the socket API client. It will also prevent the client from sending unnecessary RETRIEVE_FILE_STATUS requests. Also remove AccountState::canSync, since it does the same as isConnected and syncing is not an account responsibility. --- src/gui/accountstate.cpp | 8 +++----- src/gui/accountstate.h | 4 +--- src/gui/folder.cpp | 7 +++++-- src/gui/folder.h | 3 +-- src/gui/folderman.cpp | 17 +++++++++++++++-- src/gui/folderman.h | 1 + src/gui/socketapi.cpp | 31 ++++++++++++++++++------------- src/gui/socketapi.h | 1 + 8 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/gui/accountstate.cpp b/src/gui/accountstate.cpp index 36da88e30..924317d76 100644 --- a/src/gui/accountstate.cpp +++ b/src/gui/accountstate.cpp @@ -95,6 +95,9 @@ void AccountState::setState(State state) } else if (oldState == SignedOut && _state == Disconnected) { checkConnectivity(); } + if (oldState == Connected || _state == Connected) { + emit isConnectedChanged(); + } } // might not have changed but the underlying _connectionErrors might have @@ -149,11 +152,6 @@ bool AccountState::isConnectedOrTemporarilyUnavailable() const return isConnected() || _state == ServiceUnavailable; } -bool AccountState::canSync() const -{ - return isConnected(); -} - void AccountState::tagLastSuccessfullETagRequest() { _timeSinceLastETagCheck.restart(); diff --git a/src/gui/accountstate.h b/src/gui/accountstate.h index 6ba0add89..61489c30c 100644 --- a/src/gui/accountstate.h +++ b/src/gui/accountstate.h @@ -102,9 +102,6 @@ public: bool isConnected() const; bool isConnectedOrTemporarilyUnavailable() const; - /// Returns whether sync actions are allowed to run. - bool canSync() const; - /// Triggers a ping to the server to update state and /// connection status and errors. void checkConnectivity(); @@ -130,6 +127,7 @@ private: signals: void stateChanged(int state); + void isConnectedChanged(); protected Q_SLOTS: void slotConnectionValidatorResult(ConnectionValidator::Status status, const QStringList& errors); diff --git a/src/gui/folder.cpp b/src/gui/folder.cpp index 4984ca872..47c2c2944 100644 --- a/src/gui/folder.cpp +++ b/src/gui/folder.cpp @@ -96,6 +96,7 @@ Folder::Folder(const FolderDefinition& definition, if (!setIgnoredFiles()) qWarning("Could not read system exclude file"); + connect(_accountState.data(), SIGNAL(isConnectedChanged()), this, SIGNAL(canSyncChanged())); connect(_engine.data(), SIGNAL(rootEtag(QString)), this, SLOT(etagRetreivedFromSyncEngine(QString))); connect(_engine.data(), SIGNAL(treeWalkResult(const SyncFileItemVector&)), this, SLOT(slotThreadTreeWalkResult(const SyncFileItemVector&)), Qt::QueuedConnection); @@ -230,7 +231,7 @@ bool Folder::syncPaused() const bool Folder::canSync() const { - return !syncPaused() && accountState()->canSync(); + return !syncPaused() && accountState()->isConnected(); } void Folder::setSyncPaused( bool paused ) @@ -249,6 +250,7 @@ void Folder::setSyncPaused( bool paused ) } emit syncPausedChanged(this, paused); emit syncStateChange(); + emit canSyncChanged(); } void Folder::setSyncState(SyncResult::Status state) @@ -686,7 +688,8 @@ void Folder::wipe() QFile::remove( stateDbFile + "-wal" ); QFile::remove( stateDbFile + "-journal" ); - FolderMan::instance()->socketApi()->slotRegisterPath(alias()); + if (canSync()) + FolderMan::instance()->socketApi()->slotRegisterPath(alias()); } bool Folder::setIgnoredFiles() diff --git a/src/gui/folder.h b/src/gui/folder.h index ad2211ffa..79a27ad62 100644 --- a/src/gui/folder.h +++ b/src/gui/folder.h @@ -131,8 +131,6 @@ public: /** * Returns true when the folder may sync. - * - * !syncPaused() && accountState->canSync(). */ bool canSync() const; @@ -203,6 +201,7 @@ signals: void progressInfo(const ProgressInfo& progress); void newBigFolderDiscovered(const QString &); // A new folder bigger than the threshold was discovered void syncPausedChanged(Folder*, bool paused); + void canSyncChanged(); /** * Fires for each change inside this folder that wasn't caused diff --git a/src/gui/folderman.cpp b/src/gui/folderman.cpp index fc4268053..d39199eb2 100644 --- a/src/gui/folderman.cpp +++ b/src/gui/folderman.cpp @@ -157,7 +157,8 @@ void FolderMan::registerFolderMonitor( Folder *folder ) } // register the folder with the socket API - _socketApi->slotRegisterPath(folder->alias()); + if (folder->canSync()) + _socketApi->slotRegisterPath(folder->alias()); } void FolderMan::addMonitorPath( const QString& alias, const QString& path ) @@ -427,6 +428,17 @@ void FolderMan::slotFolderSyncPaused( Folder *f, bool paused ) } } +void FolderMan::slotFolderCanSyncChanged() +{ + Folder *f = qobject_cast(sender()); + Q_ASSERT(f); + if (f->canSync()) { + _socketApi->slotRegisterPath(f->alias()); + } else { + _socketApi->slotUnregisterPath(f->alias()); + } +} + // this really terminates the current sync process // ie. no questions, no prisoners // csync still remains in a stable state, regardless of that. @@ -549,7 +561,7 @@ void FolderMan::slotAccountStateChanged() } QString accountName = accountState->account()->displayName(); - if (accountState->canSync()) { + if (accountState->isConnected()) { qDebug() << "Account" << accountName << "connected, scheduling its folders"; foreach (Folder *f, _folderMap.values()) { @@ -820,6 +832,7 @@ Folder* FolderMan::addFolderInternal(FolderDefinition folderDefinition, AccountS connect(folder, SIGNAL(syncFinished(SyncResult)), SLOT(slotFolderSyncFinished(SyncResult))); connect(folder, SIGNAL(syncStateChange()), SLOT(slotForwardFolderSyncStateChange())); connect(folder, SIGNAL(syncPausedChanged(Folder*,bool)), SLOT(slotFolderSyncPaused(Folder*,bool))); + connect(folder, SIGNAL(canSyncChanged()), SLOT(slotFolderCanSyncChanged())); connect(&folder->syncEngine().syncFileStatusTracker(), SIGNAL(fileStatusChanged(const QString &, SyncFileStatus)), _socketApi.data(), SLOT(slotFileStatusChanged(const QString &, SyncFileStatus))); connect(folder, SIGNAL(watchedFileChangedExternally(QString)), diff --git a/src/gui/folderman.h b/src/gui/folderman.h index 62205d050..dce8a1154 100644 --- a/src/gui/folderman.h +++ b/src/gui/folderman.h @@ -144,6 +144,7 @@ signals: public slots: void slotRemoveFolder( Folder* ); void slotFolderSyncPaused(Folder *, bool paused); + void slotFolderCanSyncChanged(); void slotFolderSyncStarted(); void slotFolderSyncFinished( const SyncResult& ); diff --git a/src/gui/socketapi.cpp b/src/gui/socketapi.cpp index 06141684b..2e78cdb01 100644 --- a/src/gui/socketapi.cpp +++ b/src/gui/socketapi.cpp @@ -141,8 +141,10 @@ void SocketApi::slotNewConnection() _listeners.append(socket); foreach( Folder *f, FolderMan::instance()->map() ) { - QString message = buildRegisterPathMessage(f->path()); - sendMessage(socket, message); + if (f->canSync()) { + QString message = buildRegisterPathMessage(f->path()); + sendMessage(socket, message); + } } } @@ -181,6 +183,10 @@ void SocketApi::slotReadSocket() void SocketApi::slotRegisterPath( const QString& alias ) { + // Make sure not to register twice to each connected client + if (_registeredAliases.contains(alias)) + return; + Folder *f = FolderMan::instance()->folder(alias); if (f) { QString message = buildRegisterPathMessage(f->path()); @@ -188,13 +194,20 @@ void SocketApi::slotRegisterPath( const QString& alias ) sendMessage(socket, message); } } + + _registeredAliases.insert(alias); } void SocketApi::slotUnregisterPath( const QString& alias ) { + if (!_registeredAliases.contains(alias)) + return; + Folder *f = FolderMan::instance()->folder(alias); if (f) broadcastMessage(QLatin1String("UNREGISTER_PATH"), f->path(), QString::null, true ); + + _registeredAliases.remove(alias); } void SocketApi::slotUpdateFolderView(Folder *f) @@ -275,8 +288,6 @@ void SocketApi::command_RETRIEVE_FOLDER_STATUS(const QString& argument, QIODevic void SocketApi::command_RETRIEVE_FILE_STATUS(const QString& argument, QIODevice* socket) { - const QString nopString("NOP"); - if( !socket ) { qDebug() << "No valid socket object."; return; @@ -289,18 +300,12 @@ void SocketApi::command_RETRIEVE_FILE_STATUS(const QString& argument, QIODevice* Folder* syncFolder = FolderMan::instance()->folderForPath( argument ); if (!syncFolder) { // this can happen in offline mode e.g.: nothing to worry about - statusString = nopString; + statusString = QLatin1String("NOP"); } else { const QString file = QDir::cleanPath(argument).mid(syncFolder->cleanPath().length()+1); + SyncFileStatus fileStatus = syncFolder->syncEngine().syncFileStatusTracker().fileStatus(file); - // future: Send more specific states for paused, disconnected etc. - if( syncFolder->syncPaused() || !syncFolder->accountState()->isConnected() ) { - statusString = nopString; - } else { - SyncFileStatus fileStatus = syncFolder->syncEngine().syncFileStatusTracker().fileStatus(file); - - statusString = fileStatus.toSocketAPIString(); - } + statusString = fileStatus.toSocketAPIString(); } const QString message = QLatin1String("STATUS:") % statusString % QLatin1Char(':') % QDir::toNativeSeparators(argument); diff --git a/src/gui/socketapi.h b/src/gui/socketapi.h index 763ca2616..2b0aab74c 100644 --- a/src/gui/socketapi.h +++ b/src/gui/socketapi.h @@ -77,6 +77,7 @@ private: Q_INVOKABLE void command_SHARE_MENU_TITLE(const QString& argument, QIODevice* socket); QString buildRegisterPathMessage(const QString& path); + QSet _registeredAliases; QList _listeners; SocketApiServer _localServer; }; -- 2.39.5