[Libreoffice-commits] online.git: loleaflet/admin.strings.js loleaflet/dist loleaflet/src wsd/Admin.cpp wsd/Admin.hpp wsd/AdminModel.cpp wsd/AdminModel.hpp wsd/ClientSession.cpp wsd/DocumentBroker.cpp wsd/DocumentBroker.hpp wsd/protocol.txt

Tor Lillqvist tml at collabora.com
Thu Dec 8 08:39:29 UTC 2016


 loleaflet/admin.strings.js                 |    1 
 loleaflet/dist/admin/admin.html            |    1 
 loleaflet/src/admin/AdminSocketOverview.js |   35 ++++++++++++++++++++++++-----
 wsd/Admin.cpp                              |    5 ++++
 wsd/Admin.hpp                              |    2 +
 wsd/AdminModel.cpp                         |   16 ++++++++++++-
 wsd/AdminModel.hpp                         |   10 +++++++-
 wsd/ClientSession.cpp                      |    1 
 wsd/DocumentBroker.cpp                     |    5 ++++
 wsd/DocumentBroker.hpp                     |    2 +
 wsd/protocol.txt                           |    9 ++++++-
 11 files changed, 79 insertions(+), 8 deletions(-)

New commits:
commit e221388c795e43159dab15602856223aa1eb500e
Author: Tor Lillqvist <tml at collabora.com>
Date:   Mon Dec 5 22:11:07 2016 +0200

    Add an 'Idle time' column to the Admin console
    
    Use a new protocol message, 'resetidle' to inform Admin clients
    whenever a user has done anything in a document view. This is a
    message that Admin clients need to subscribe to.
    
    Also add the current idle time for each document to the 'documents'
    message.
    
    To reduce protocol chatter, the idle time is updated at most once per
    10 s.
    
    Change-Id: I418e82b05048a3628f21dcd240ccd974b3a01356
    Reviewed-on: https://gerrit.libreoffice.org/31653
    Reviewed-by: Tor Lillqvist <tml at collabora.com>
    Tested-by: Tor Lillqvist <tml at collabora.com>

diff --git a/loleaflet/admin.strings.js b/loleaflet/admin.strings.js
index c9bfbbb..fcfb574 100644
--- a/loleaflet/admin.strings.js
+++ b/loleaflet/admin.strings.js
@@ -16,6 +16,7 @@ l10nstrings.strPid = _('PID');
 l10nstrings.strDocument = _('Document');
 l10nstrings.strNumberOfViews = _('Number of views');
 l10nstrings.strElapsedTime = _('Elapsed time');
+l10nstrings.strIdleTime = _('Idle time');
 l10nstrings.strKill = _('Kill');
 l10nstrings.strGraphs = _('Graphs');
 l10nstrings.strSave = _('Save');
diff --git a/loleaflet/dist/admin/admin.html b/loleaflet/dist/admin/admin.html
index 8e41f12..0d44ea4 100644
--- a/loleaflet/dist/admin/admin.html
+++ b/loleaflet/dist/admin/admin.html
@@ -88,6 +88,7 @@
 		  <th><script>document.write(l10nstrings.strNumberOfViews)</script></th>
 		  <th><script>document.write(l10nstrings.strMemoryConsumed)</script></th>
 		  <th><script>document.write(l10nstrings.strElapsedTime)</script></th>
+		  <th><script>document.write(l10nstrings.strIdleTime)</script></th>
 		</tr>
 	      </thead>
 	      <tbody id="doclist">
diff --git a/loleaflet/src/admin/AdminSocketOverview.js b/loleaflet/src/admin/AdminSocketOverview.js
index 068c60d..3bfdafe 100644
--- a/loleaflet/src/admin/AdminSocketOverview.js
+++ b/loleaflet/src/admin/AdminSocketOverview.js
@@ -23,7 +23,7 @@ var AdminSocketOverview = AdminSocketBase.extend({
 		this.base.call(this);
 
 		this.socket.send('documents');
-		this.socket.send('subscribe adddoc rmdoc');
+		this.socket.send('subscribe adddoc rmdoc resetidle');
 
 		this._getBasicStats();
 		var socketOverview = this;
@@ -39,6 +39,11 @@ var AdminSocketOverview = AdminSocketBase.extend({
 				$(this).val(newSecs);
 				$(this).html(Util.humanizeSecs(newSecs));
 			});
+			$('td.idle_time').each(function() {
+				var newSecs = parseInt($(this).val()) + 1;
+				$(this).val(newSecs);
+				$(this).html(Util.humanizeSecs(newSecs));
+			});
 		}, 1000);
 
 		// Allow table rows to have a context menu for terminating sessions
@@ -80,7 +85,7 @@ var AdminSocketOverview = AdminSocketBase.extend({
 		}
 
 		var $rowContainer;
-		var $pid, $name, $views, $mem, $docTime, $doc, $a;
+		var $pid, $name, $views, $mem, $docTime, $docIdle, $doc, $a;
 		var nViews, nTotalViews;
 		var docProps, sPid, sName, sViews, sMem, sDocTime;
 		if (textMsg.startsWith('documents')) {
@@ -93,7 +98,9 @@ var AdminSocketOverview = AdminSocketBase.extend({
 				sViews = docProps[2];
 				sMem = docProps[3];
 				sDocTime = docProps[4];
+				sDocIdle = docProps[5];
 
+				$doc = $('#doc' + sPid);
 				$rowContainer = $(document.createElement('tr')).attr('id', 'doc' + sPid);
 
 				$pid = $(document.createElement('td')).text(sPid);
@@ -103,20 +110,32 @@ var AdminSocketOverview = AdminSocketBase.extend({
 				$rowContainer.append($name);
 
 				$views = $(document.createElement('td')).attr('id', 'docview' + sPid)
-					                                    .text(sViews);
+									    .text(sViews);
 				$rowContainer.append($views);
 
 				$mem = $(document.createElement('td')).text(Util.humanizeMem(parseInt(sMem)));
 				$rowContainer.append($mem);
 
 				$docTime = $(document.createElement('td')).addClass('elapsed_time')
-					                                      .val(parseInt(sDocTime))
-					                                      .text(Util.humanizeSecs(sDocTime));
+									      .val(parseInt(sDocTime))
+									      .text(Util.humanizeSecs(sDocTime));
 				$rowContainer.append($docTime);
 
+				$docIdle = $(document.createElement('td')).attr('id', 'docidle' + sPid)
+									      .addClass('idle_time')
+									      .val(parseInt(sDocIdle))
+									      .text(Util.humanizeSecs(sDocIdle));
+				$rowContainer.append($docIdle);
 				$('#doclist').append($rowContainer);
 			}
 		}
+		else if (textMsg.startsWith('resetidle')) {
+			textMsg = textMsg.substring('resetidle'.length);
+			docProps = textMsg.trim().split(' ');
+			sPid = docProps[0];
+			var $idle = $(document.getElementById('docidle' + sPid));
+			$idle.val(0).text(Util.humanizeSecs(0));
+		}
 		else if (textMsg.startsWith('adddoc')) {
 			textMsg = textMsg.substring('adddoc'.length);
 			docProps = textMsg.trim().split(' ');
@@ -147,6 +166,12 @@ var AdminSocketOverview = AdminSocketBase.extend({
 					                                      .text(Util.humanizeSecs(0));
 				$rowContainer.append($docTime);
 
+				$docIdle = $(document.createElement('td')).attr('id', 'docidle' + sPid)
+									      .addClass('idle_time')
+					                                      .val(0)
+					                                      .text(Util.humanizeSecs(0));
+				$rowContainer.append($docIdle);
+
 				$('#doclist').append($rowContainer);
 
 				$a = $(document.getElementById('active_docs_count'));
diff --git a/wsd/Admin.cpp b/wsd/Admin.cpp
index 09a561e..73b23f7 100644
--- a/wsd/Admin.cpp
+++ b/wsd/Admin.cpp
@@ -388,4 +388,9 @@ AdminModel& Admin::getModel()
     return _model;
 }
 
+void Admin::updateLastActivityTime(const std::string& docKey)
+{
+    _model.updateLastActivityTime(docKey);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/wsd/Admin.hpp b/wsd/Admin.hpp
index cb5d83f..2c88cd2 100644
--- a/wsd/Admin.hpp
+++ b/wsd/Admin.hpp
@@ -94,6 +94,8 @@ public:
 
     std::unique_lock<std::mutex> getLock() { return std::unique_lock<std::mutex>(_modelMutex); }
 
+    void updateLastActivityTime(const std::string& docKey);
+
 private:
     Admin();
 
diff --git a/wsd/AdminModel.cpp b/wsd/AdminModel.cpp
index 1099a0d..2f71486 100644
--- a/wsd/AdminModel.cpp
+++ b/wsd/AdminModel.cpp
@@ -351,11 +351,25 @@ std::string AdminModel::getDocuments() const
                 << encodedFilename << ' '
                 << it.second.getActiveViews() << ' '
                 << Util::getMemoryUsage(it.second.getPid()) << ' '
-                << it.second.getElapsedTime() << " \n ";
+                << it.second.getElapsedTime() << ' '
+                << it.second.getIdleTime() << " \n ";
         }
     }
 
     return oss.str();
 }
 
+void AdminModel::updateLastActivityTime(const std::string& docKey)
+{
+    auto docIt = _documents.find(docKey);
+    if (docIt != _documents.end())
+    {
+        if (docIt->second.getIdleTime() >= 10)
+        {
+            docIt->second.updateLastActivityTime();
+            notify("resetidle " + std::to_string(docIt->second.getPid()));
+        }
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/wsd/AdminModel.hpp b/wsd/AdminModel.hpp
index f2163b5..1dce29c 100644
--- a/wsd/AdminModel.hpp
+++ b/wsd/AdminModel.hpp
@@ -49,7 +49,8 @@ public:
         : _docKey(docKey),
           _pid(pid),
           _filename(filename),
-          _start(std::time(nullptr))
+          _start(std::time(nullptr)),
+          _lastActivity(_start)
     {
     }
 
@@ -61,6 +62,8 @@ public:
 
     std::time_t getElapsedTime() const { return std::time(nullptr) - _start; }
 
+    std::time_t getIdleTime() const { return std::time(nullptr) - _lastActivity; }
+
     void addView(const std::string& sessionId);
 
     int expireView(const std::string& sessionId);
@@ -69,6 +72,8 @@ public:
 
     const std::map<std::string, View>& getViews() const { return _views; }
 
+    void updateLastActivityTime() { _lastActivity = std::time(nullptr); }
+
 private:
     const std::string _docKey;
     const Poco::Process::PID _pid;
@@ -80,6 +85,7 @@ private:
     std::string _filename;
 
     std::time_t _start;
+    std::time_t _lastActivity;
     std::time_t _end = 0;
 };
 
@@ -166,6 +172,8 @@ public:
     void removeDocument(const std::string& docKey, const std::string& sessionId);
     void removeDocument(const std::string& docKey);
 
+    void updateLastActivityTime(const std::string& docKey);
+
 private:
     std::string getMemStats();
 
diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp
index 0bd20fc..9e01217 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -91,6 +91,7 @@ bool ClientSession::_handleInput(const char *buffer, int length)
     {
         // Keep track of timestamps of incoming client messages that indicate user activity.
         updateLastActivityTime();
+        docBroker->updateLastActivityTime();
     }
 
     if (tokens[0] == "loolclient")
diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp
index 2251cd0..4a78f3b 100644
--- a/wsd/DocumentBroker.cpp
+++ b/wsd/DocumentBroker.cpp
@@ -1028,4 +1028,9 @@ void DocumentBroker::closeDocument(const std::string& reason)
     terminateChild(lock, reason);
 }
 
+void DocumentBroker::updateLastActivityTime()
+{
+    Admin::instance().updateLastActivityTime(_docKey);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/wsd/DocumentBroker.hpp b/wsd/DocumentBroker.hpp
index f31471a..758ece1 100644
--- a/wsd/DocumentBroker.hpp
+++ b/wsd/DocumentBroker.hpp
@@ -301,6 +301,8 @@ public:
 
     std::unique_lock<std::mutex> getLock() { return std::unique_lock<std::mutex>(_mutex); }
 
+    void updateLastActivityTime();
+
 private:
     /// Sends the .uno:Save command to LoKit.
     bool sendUnoSave(const bool dontSaveIfUnmodified);
diff --git a/wsd/protocol.txt b/wsd/protocol.txt
index d8f1231..513c27b 100644
--- a/wsd/protocol.txt
+++ b/wsd/protocol.txt
@@ -548,6 +548,11 @@ section). Others are just response messages to some client command.
     <memory consumed> in kilobytes sent from admin -> client after every
     mem_stats_interval (see `set` command for list of settings)
 
+[*] resetidle <pid>
+
+    <pid> process id hosting the document
+    reset the idle time counter for the document
+
 InvalidAuthToken
 
     This is sent when invalid auth token is provided in 'auth' command. See
@@ -557,11 +562,13 @@ NotAuthenticated
 
     When client sends an admin command that requires authentication.
 
-documents <pid> <filename> <number of views> <memory consumed> <elapsed time>
+documents <pid> <filename> <number of views> <memory consumed> <elapsed time> <idle time>
 <pid> <filename> ....
 ...
 
     <elapsed time> is in seconds since the first view of the document was opened
+    <idle time> is in seconds since some user did something in his view of the document (even just moving
+        the insertion cursor)
     <number of views> Number of users/views opening this(<pid>) document
     Other parameters are same as mentioned in `adddoc`
 


More information about the Libreoffice-commits mailing list