loolwsd/ChildProcessSession.cpp | 28 ++++++++++++++++++++++++++++ loolwsd/ChildProcessSession.hpp | 31 +++++++++++++++++++++++++++++++ loolwsd/LOOLKit.cpp | 13 +++++++++++-- loolwsd/MasterProcessSession.cpp | 1 - 4 files changed, 70 insertions(+), 3 deletions(-)
New commits: commit 904bf929f19084d3b71be758bfdde89d1c55d8ac Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> Date: Sun Jan 24 15:24:11 2016 -0500 loolwsd: throttle traffic for inactive sessions Sessions that have been inactive for a certain duration, currently set at 120 seconds, will not receive updates. A new statistics class tracks the activity of every session and blocks callback updates from reaching inactive clients. Change-Id: I64296488b2c0be0598b218ba89a6d02f057a5f7e Reviewed-on: https://gerrit.libreoffice.org/21760 Reviewed-by: Ashod Nakashian <ashnak...@gmail.com> Tested-by: Ashod Nakashian <ashnak...@gmail.com> diff --git a/loolwsd/ChildProcessSession.cpp b/loolwsd/ChildProcessSession.cpp index 5edc7b5..e89eb82 100644 --- a/loolwsd/ChildProcessSession.cpp +++ b/loolwsd/ChildProcessSession.cpp @@ -90,6 +90,34 @@ bool ChildProcessSession::handleDisconnect(Poco::StringTokenizer& tokens) bool ChildProcessSession::_handleInput(const char *buffer, int length) { + if (isInactive() && _loKitDocument != nullptr) + { + Log::debug("Handling message after inactivity of " + std::to_string(_stats.getInactivityMS()) + "ms."); + + // Client is getting active again. + // Send invalidation and other sync-up messages. + std::unique_lock<std::recursive_mutex> lock(Mutex); + + if (_multiView) + _loKitDocument->pClass->setView(_loKitDocument, _viewId); + + int curPart = _loKitDocument->pClass->getPart(_loKitDocument); + sendTextFrame("curpart: part=" + std::to_string(curPart)); + if (getDocType() == "text") + { + curPart = 0; + } + + sendTextFrame("invalidatetiles:" + " part=" + std::to_string(curPart) + + " x=0 y=0" + " width=" + std::to_string(INT_MAX) + + " height=" + std::to_string(INT_MAX)); + + //TODO: Sync cursor. + } + + _stats.updateLastActivityTime(); const std::string firstLine = getFirstLine(buffer, length); StringTokenizer tokens(firstLine, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM); diff --git a/loolwsd/ChildProcessSession.hpp b/loolwsd/ChildProcessSession.hpp index 6d9f326..f0b47b3 100644 --- a/loolwsd/ChildProcessSession.hpp +++ b/loolwsd/ChildProcessSession.hpp @@ -24,6 +24,30 @@ static int ClientPortNumber = DEFAULT_CLIENT_PORT_NUMBER; class ChildProcessSession final : public LOOLSession { public: + class Statistics + { + public: + Statistics() : + _lastActivityTime(std::chrono::steady_clock::now()) + { + } + + void updateLastActivityTime() + { + _lastActivityTime = std::chrono::steady_clock::now(); + } + + double getInactivityMS() const + { + const auto duration = (std::chrono::steady_clock::now() - _lastActivityTime); + return std::chrono::duration_cast<std::chrono::milliseconds>(duration).count(); + } + + private: + std::chrono::steady_clock::time_point _lastActivityTime; + }; + +public: /// Create a new ChildProcessSession /// ws The socket between master and kit (jailed). /// loKit The LOKit instance. @@ -57,6 +81,9 @@ public: std::unique_lock<std::recursive_mutex> getLock() { return std::unique_lock<std::recursive_mutex>(Mutex); } + const Statistics& getStatistics() const { return _stats; } + bool isInactive() const { return _stats.getInactivityMS() >= InactivityThresholdMS; } + protected: virtual bool loadDocument(const char *buffer, int length, Poco::StringTokenizer& tokens) override; @@ -96,10 +123,14 @@ private: int _clientPart; std::function<LibreOfficeKitDocument*(const std::string&, const std::string&)> _onLoad; std::function<void(const std::string&)> _onUnload; + /// Statistics and activity tracking. + Statistics _stats; /// Synchronize _loKitDocument acess. /// This should be inside LoKit. static std::recursive_mutex Mutex; + + static constexpr auto InactivityThresholdMS = 120 * 1000; }; #endif diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp index 67966ef..f542ec2 100644 --- a/loolwsd/LOOLKit.cpp +++ b/loolwsd/LOOLKit.cpp @@ -144,6 +144,16 @@ public: Log::trace() << "Callback [" << pSession->getViewId() << "] " << callbackTypeToString(nType) << " [" << rPayload << "]." << Log::end; + if (pSession->isDisconnected()) + { + Log::trace("Skipping callback on disconnected session " + pSession->getName()); + return; + } + else if (pSession->isInactive()) + { + Log::trace("Skipping callback on inactive session " + pSession->getName()); + return; + } switch (static_cast<LibreOfficeKitCallbackType>(nType)) { @@ -424,8 +434,7 @@ public: queue.put("eof"); queueHandlerThread.join(); - _session->sendTextFrame("disconnect"); - _session->sendTextFrame("eof"); + _session->disconnect(); } catch (const Exception& exc) { diff --git a/loolwsd/MasterProcessSession.cpp b/loolwsd/MasterProcessSession.cpp index 8c101c2..15fb1f4 100644 --- a/loolwsd/MasterProcessSession.cpp +++ b/loolwsd/MasterProcessSession.cpp @@ -88,7 +88,6 @@ bool MasterProcessSession::handleDisconnect(Poco::StringTokenizer& tokens) "]."); LOOLSession::handleDisconnect(tokens); - disconnect(tokens.count() > 1 ? tokens[1] : std::string()); auto peer = _peer.lock(); if (peer) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits