[Libreoffice-commits] online.git: loolwsd/Admin.cpp loolwsd/Admin.hpp loolwsd/AdminModel.hpp loolwsd/LOOLWSD.cpp loolwsd/Util.cpp loolwsd/Util.hpp

Pranav Kant pranavk at collabora.com
Tue Mar 8 09:35:09 UTC 2016


 loolwsd/Admin.cpp      |   31 ++++++++++++++++--
 loolwsd/Admin.hpp      |    5 +-
 loolwsd/AdminModel.hpp |   82 ++++++++++++++++++++++++++-----------------------
 loolwsd/LOOLWSD.cpp    |    2 -
 loolwsd/Util.cpp       |   31 ++++++++++++++++++
 loolwsd/Util.hpp       |    2 +
 6 files changed, 109 insertions(+), 44 deletions(-)

New commits:
commit 76542d8d528953fdfcf38b55b6eb4a96fcbbd99b
Author: Pranav Kant <pranavk at collabora.com>
Date:   Sat Mar 5 00:19:01 2016 +0530

    loolwsd: Add total memory, total active docs, total active users
    
    Further changes/refactoring to make it possible:
    * Add broker pid to Admin class
    * Move getMemoryUsage for process to Util
    * Change variable name to accurately reflect *active* items
      _nViews -> _nActiveViews, etc.
    
    Change-Id: I4c9206c49ab829b73ebfe226874bfbbcc8f95342
    Reviewed-on: https://gerrit.libreoffice.org/22989
    Reviewed-by: Tor Lillqvist <tml at collabora.com>
    Tested-by: Tor Lillqvist <tml at collabora.com>

diff --git a/loolwsd/Admin.cpp b/loolwsd/Admin.cpp
index c8bcdd6..c4a6d33 100644
--- a/loolwsd/Admin.cpp
+++ b/loolwsd/Admin.cpp
@@ -112,7 +112,10 @@ public:
                             break;
                         }
 
-                        if (tokens.count() == 1 && tokens[0] == "stats")
+                        if (tokens.count() < 1)
+                            continue;
+
+                        if (tokens[0] == "stats")
                         {
                             //TODO: Collect stats and reply back to admin.
                             // We need to ask Broker to give us some numbers on docs/clients/etc.
@@ -140,12 +143,32 @@ public:
 
                             ws->sendFrame(statsResponse.data(), statsResponse.size());
                         }
-                        else if (tokens.count() == 1 && tokens[0] == "documents")
+                        else if (tokens[0] == "documents")
                         {
 
                             std::string responseString = "documents " + model.query("documents");
                             ws->sendFrame(responseString.data(), responseString.size());
                         }
+                        else if (tokens[0] == "total_mem")
+                        {
+                            Poco::Process::PID nBrokerPid = _admin->getBrokerPid();
+                            unsigned totalMem = Util::getMemoryUsage(nBrokerPid);
+                            totalMem += model.getTotalMemoryUsage();
+                            totalMem += Util::getMemoryUsage(Poco::Process::id());
+
+                            std::string response = "total_mem " + std::to_string(totalMem);
+                            ws->sendFrame(response.data(), response.size());
+                        }
+                        else if (tokens[0] == "active_users_count")
+                        {
+                            std::string response = tokens[0] + " " + model.query(tokens[0]);
+                            ws->sendFrame(response.data(), response.size());
+                        }
+                        else if (tokens[0] == "active_docs_count")
+                        {
+                            std::string response = tokens[0] + " " + model.query(tokens[0]);
+                            ws->sendFrame(response.data(), response.size());
+                        }
                         else if (tokens[0] == "kill" && tokens.count() == 2)
                         {
                             try
@@ -226,10 +249,11 @@ private:
 };
 
 /// An admin command processor.
-Admin::Admin(const int brokerPipe, const int notifyPipe) :
+Admin::Admin(const Poco::Process::PID brokerPid, const int brokerPipe, const int notifyPipe) :
     _srv(new AdminRequestHandlerFactory(this), ServerSocket(ADMIN_PORT_NUMBER), new HTTPServerParams),
     _model(AdminModel())
 {
+    Admin::BrokerPid = brokerPid;
     Admin::BrokerPipe = brokerPipe;
     Admin::NotifyPipe = notifyPipe;
 }
@@ -278,6 +302,7 @@ AdminModel& Admin::getModel()
 }
 
 //TODO: Clean up with something more elegant.
+Poco::Process::PID Admin::BrokerPid;
 int Admin::BrokerPipe;
 int Admin::NotifyPipe;
 
diff --git a/loolwsd/Admin.hpp b/loolwsd/Admin.hpp
index 839544e..c02f824 100644
--- a/loolwsd/Admin.hpp
+++ b/loolwsd/Admin.hpp
@@ -22,11 +22,11 @@ const std::string FIFO_NOTIFY = "loolnotify.fifo";
 class Admin : public Poco::Runnable
 {
 public:
-    Admin(const int brokerPipe, const int notifyPipe);
+    Admin(const Poco::Process::PID brokerPid, const int brokerPipe, const int notifyPipe);
 
     ~Admin();
 
-    static int getBrokerPid() { return Admin::BrokerPipe; }
+    static int getBrokerPid() { return Admin::BrokerPid; }
 
     static int getBrokerPipe() { return Admin::BrokerPipe; }
 
@@ -41,6 +41,7 @@ private:
     Poco::Net::HTTPServer _srv;
     AdminModel _model;
 
+    static Poco::Process::PID BrokerPid;
     static int BrokerPipe;
     static int NotifyPipe;
 };
diff --git a/loolwsd/AdminModel.hpp b/loolwsd/AdminModel.hpp
index 4e00446..755a6aa 100644
--- a/loolwsd/AdminModel.hpp
+++ b/loolwsd/AdminModel.hpp
@@ -35,7 +35,7 @@ public:
 
     bool isExpired()
     {
-        return _end != 0 && std::time(nullptr) > _end;
+        return _end != 0 && std::time(nullptr) >= _end;
     }
 
 private:
@@ -78,7 +78,7 @@ public:
 
     bool isExpired() const
     {
-        return _end != 0 && std::time(nullptr) > _end;
+        return _end != 0 && std::time(nullptr) >= _end;
     }
 
     void addView(int nSessionId)
@@ -91,7 +91,7 @@ public:
         }
         else
         {
-            _nViews++;
+            _nActiveViews++;
         }
     }
 
@@ -101,13 +101,13 @@ public:
         if (it != _views.end())
         {
             it->second.expire();
-            _nViews--;
+            _nActiveViews--;
         }
     }
 
-    unsigned getTotalViews() const
+    unsigned getActiveViews() const
     {
-        return _nViews;
+        return _nActiveViews;
     }
 
 private:
@@ -115,7 +115,7 @@ private:
     /// SessionId mapping to View object
     std::map<int, View> _views;
     /// Total number of active views
-    unsigned _nViews = 0;
+    unsigned _nActiveViews = 0;
     /// Hosted URL
     std::string _sUrl;
 
@@ -183,7 +183,7 @@ public:
         if (tokens[0] == "document")
         {
             addDocument(std::stoi(tokens[1]), tokens[2]);
-            unsigned mem = getMemoryUsage(std::stoi(tokens[1]));
+            unsigned mem = Util::getMemoryUsage(std::stoi(tokens[1]));
             std::string response = data + std::to_string(mem);
             notify(response);
             return;
@@ -222,39 +222,31 @@ public:
         {
             return getDocuments();
         }
+        else if (tokens[0] == "active_users_count")
+        {
+            return std::to_string(getTotalActiveViews());
+        }
+        else if (tokens[0] == "active_docs_count")
+        {
+            return std::to_string(_nActiveDocuments);
+        }
 
         return std::string("");
     }
 
-    unsigned getMemoryUsage(Poco::Process::PID nPid)
+    /// Returns memory consumed by all active loolkit processes
+    unsigned getTotalMemoryUsage()
     {
-        //TODO: Instead of RSS, show PSS
-        std::string sResponse;
-        const auto cmd = "ps o rss= -p " + std::to_string(nPid);
-        FILE* fp = popen(cmd.c_str(), "r");
-        if (fp == nullptr)
-        {
-            return 0;
-        }
-
-        char cmdBuffer[1024];
-        while (fgets(cmdBuffer, sizeof(cmdBuffer) - 1, fp) != nullptr)
+        unsigned totalMem = 0;
+        for (auto& it: _documents)
         {
-            sResponse += cmdBuffer;
-        }
-        pclose(fp);
+            if (it.second.isExpired())
+                continue;
 
-        unsigned nMem = 0;
-        try
-        {
-            nMem = std::stoi(sResponse);
-        }
-        catch(std::exception& e)
-        {
-            Log::warn() << "Trying to find memory of invalid/dead PID" << Log::end;
+            totalMem += Util::getMemoryUsage(it.second.getPid());
         }
 
-        return nMem;
+        return totalMem;
     }
 
     void subscribe(std::shared_ptr<Poco::Net::WebSocket>& ws)
@@ -275,17 +267,17 @@ private:
         }
         else
         {
-            _nDocuments++;
+            _nActiveDocuments++;
         }
     }
 
     void removeDocument(Poco::Process::PID pid)
     {
         auto it = _documents.find(pid);
-        if (it != _documents.end())
+        if (it != _documents.end() && !it->second.isExpired())
         {
             it->second.expire();
-            _nDocuments--;
+            _nActiveDocuments--;
         }
     }
 
@@ -305,6 +297,20 @@ private:
         }
     }
 
+    unsigned getTotalActiveViews()
+    {
+        unsigned nTotalViews = 0;
+        for (auto& it: _documents)
+        {
+            if (it.second.isExpired())
+                continue;
+
+            nTotalViews += it.second.getActiveViews();
+        }
+
+        return nTotalViews;
+    }
+
     std::string getDocuments()
     {
         std::ostringstream oss;
@@ -315,8 +321,8 @@ private:
 
             std::string sPid = std::to_string(it.second.getPid());
             std::string sUrl = it.second.getUrl();
-            std::string sViews = std::to_string(it.second.getTotalViews());
-            std::string sMem = std::to_string(getMemoryUsage(it.second.getPid()));
+            std::string sViews = std::to_string(it.second.getActiveViews());
+            std::string sMem = std::to_string(Util::getMemoryUsage(it.second.getPid()));
 
             oss << sPid << " "
                 << sUrl << " "
@@ -332,7 +338,7 @@ private:
     std::map<Poco::Process::PID, Document> _documents;
 
     /// Number of active documents
-    unsigned _nDocuments;
+    unsigned _nActiveDocuments = 0;
 };
 
 #endif
diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp
index 019d916..dee237c 100644
--- a/loolwsd/LOOLWSD.cpp
+++ b/loolwsd/LOOLWSD.cpp
@@ -1033,7 +1033,7 @@ int LOOLWSD::main(const std::vector<std::string>& /*args*/)
     }
 
     // Start the Admin manager.
-    Admin admin(BrokerWritePipe, notifyPipe);
+    Admin admin(brokerPid, BrokerWritePipe, notifyPipe);
     threadPool.start(admin);
 
     TestInput input(*this, svs, srv);
diff --git a/loolwsd/Util.cpp b/loolwsd/Util.cpp
index dc419c8..e4d1352 100644
--- a/loolwsd/Util.cpp
+++ b/loolwsd/Util.cpp
@@ -598,6 +598,37 @@ namespace Util
             }
         }
     }
+
+    unsigned getMemoryUsage(Poco::Process::PID nPid)
+    {
+        //TODO: Instead of RSS, return PSS
+        std::string sResponse;
+        const auto cmd = "ps o rss= -p " + std::to_string(nPid);
+        FILE* fp = popen(cmd.c_str(), "r");
+        if (fp == nullptr)
+        {
+            return 0;
+        }
+
+        char cmdBuffer[1024];
+        while (fgets(cmdBuffer, sizeof(cmdBuffer) - 1, fp) != nullptr)
+        {
+            sResponse += cmdBuffer;
+        }
+        pclose(fp);
+
+        unsigned nMem = 0;
+        try
+        {
+            nMem = std::stoi(sResponse);
+        }
+        catch(std::exception& e)
+        {
+            Log::warn() << "Trying to find memory of invalid/dead PID" << Log::end;
+        }
+
+        return nMem;
+    }
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/loolwsd/Util.hpp b/loolwsd/Util.hpp
index b4d8251..1e6e515 100644
--- a/loolwsd/Util.hpp
+++ b/loolwsd/Util.hpp
@@ -126,6 +126,8 @@ namespace Util
 
     void pollPipeForReading(pollfd& pollPipe, const std::string& targetPipeName , const int& targetPipe,
                             std::function<void(std::string& message)> handler);
+
+    unsigned getMemoryUsage(Poco::Process::PID nPid);
 };
 
 //TODO: Move to own file.


More information about the Libreoffice-commits mailing list