loolwsd/LOOLStress.cpp |  159 ++++++++++++++++++++++++++-----------------------
 loolwsd/TraceFile.hpp  |   14 ++--
 2 files changed, 94 insertions(+), 79 deletions(-)

New commits:
commit f9ec1bade3325fc4c3505b60ef63665d32e38739
Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk>
Date:   Thu Aug 4 12:17:22 2016 -0400

    loolstress: time-accurate replay
    
    Change-Id: I1aff521f042c61916ef6ddfc50c2fe06c41b29ee
    Reviewed-on: https://gerrit.libreoffice.org/27968
    Reviewed-by: Ashod Nakashian <ashnak...@gmail.com>
    Tested-by: Ashod Nakashian <ashnak...@gmail.com>

diff --git a/loolwsd/LOOLStress.cpp b/loolwsd/LOOLStress.cpp
index f60aa55..f042901 100644
--- a/loolwsd/LOOLStress.cpp
+++ b/loolwsd/LOOLStress.cpp
@@ -124,108 +124,119 @@ public:
 
     void run() override
     {
-        const auto epochStart(std::chrono::steady_clock::now());
         try
         {
-            for (;;)
+            doRun();
+        }
+        catch (const Poco::Exception &e)
+        {
+            std::cerr << "Error: " << e.name() << ' '
+                      << e.message() << std::endl;
+        }
+    }
+
+private:
+
+    void doRun()
+    {
+        auto epochFile(_traceFile.getEpoch());
+        auto epochCurrent(std::chrono::steady_clock::now());
+        for (;;)
+        {
+            const auto rec = _traceFile.getNextRecord();
+            if (rec.Dir == TraceFileRecord::Direction::Invalid)
             {
-                const auto rec = _traceFile.getNextRecord();
-                if (rec.Dir == TraceFileRecord::Direction::Invalid)
-                {
-                    // End of trace file.
-                    break;
-                }
+                // End of trace file.
+                break;
+            }
 
-                const auto delta = (epochStart - 
std::chrono::steady_clock::now());
-                const auto delay = rec.TimestampNs - 
std::chrono::duration_cast<std::chrono::microseconds>(delta).count();
-                if (delay > 0)
-                {
-                    
std::this_thread::sleep_for(std::chrono::microseconds(delay));
-                }
+            const auto deltaCurrent = 
std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now()
 - epochCurrent).count();
+            const auto deltaFile = rec.TimestampNs - epochFile;
+            const auto delay = deltaFile - deltaCurrent;
+            if (delay > 0)
+            {
+                std::this_thread::sleep_for(std::chrono::microseconds(delay));
+            }
 
-                if (rec.Dir == TraceFileRecord::Direction::Event)
-                {
-                    // Meta info about about an event.
-                    static const std::string NewSession("NewSession: ");
-                    static const std::string EndSession("EndSession: ");
+            if (rec.Dir == TraceFileRecord::Direction::Event)
+            {
+                // Meta info about about an event.
+                static const std::string NewSession("NewSession: ");
+                static const std::string EndSession("EndSession: ");
 
-                    if (rec.Payload.find(NewSession) == 0)
+                if (rec.Payload.find(NewSession) == 0)
+                {
+                    const auto& uri = rec.Payload.substr(NewSession.size());
+                    auto it = Sessions.find(uri);
+                    if (it != Sessions.end())
                     {
-                        const auto& uri = 
rec.Payload.substr(NewSession.size());
-                        auto it = Sessions.find(uri);
-                        if (it != Sessions.end())
+                        // Add a new session.
+                        if (it->second.find(rec.SessionId) != it->second.end())
                         {
-                            // Add a new session.
-                            if (it->second.find(rec.SessionId) != 
it->second.end())
-                            {
-                                std::cerr << "ERROR: session [" << 
rec.SessionId << "] already exists on doc [" << uri << "]\n";
-                            }
-                            else
-                            {
-                                it->second.emplace(rec.SessionId, 
Connection::create(_app._serverURI, uri, rec.SessionId));
-                            }
+                            std::cerr << "ERROR: session [" << rec.SessionId 
<< "] already exists on doc [" << uri << "]\n";
                         }
                         else
                         {
-                            std::cerr << "New Document: " << uri << "\n";
-                            ChildToDoc.emplace(rec.Pid, uri);
-                            Sessions[uri].emplace(rec.SessionId, 
Connection::create(_app._serverURI, uri, rec.SessionId));
+                            it->second.emplace(rec.SessionId, 
Connection::create(_app._serverURI, uri, rec.SessionId));
                         }
                     }
-                    else if (rec.Payload.find(EndSession) == 0)
+                    else
                     {
-                        const auto& uri = 
rec.Payload.substr(EndSession.size());
-                        auto it = Sessions.find(uri);
-                        if (it != Sessions.end())
-                        {
-                            std::cerr << "EndSession [" << rec.SessionId << 
"]: " << uri << "\n";
-
-                            it->second.erase(rec.SessionId);
-                            if (it->second.empty())
-                            {
-                                std::cerr << "End Doc [" << uri << "].\n";
-                                Sessions.erase(it);
-                                ChildToDoc.erase(rec.Pid);
-                            }
-                        }
-                        else
-                        {
-                            std::cerr << "ERROR: Doc [" << uri << "] does not 
exist.\n";
-                        }
+                        std::cerr << "New Document: " << uri << "\n";
+                        ChildToDoc.emplace(rec.Pid, uri);
+                        Sessions[uri].emplace(rec.SessionId, 
Connection::create(_app._serverURI, uri, rec.SessionId));
                     }
                 }
-                else if (rec.Dir == TraceFileRecord::Direction::Incoming)
+                else if (rec.Payload.find(EndSession) == 0)
                 {
-                    auto docIt = ChildToDoc.find(rec.Pid);
-                    if (docIt != ChildToDoc.end())
+                    const auto& uri = rec.Payload.substr(EndSession.size());
+                    auto it = Sessions.find(uri);
+                    if (it != Sessions.end())
                     {
-                        const auto& uri = docIt->second;
-                        auto it = Sessions.find(uri);
-                        if (it != Sessions.end())
+                        std::cerr << "EndSession [" << rec.SessionId << "]: " 
<< uri << "\n";
+
+                        it->second.erase(rec.SessionId);
+                        if (it->second.empty())
                         {
-                            const auto sessionIt = 
it->second.find(rec.SessionId);
-                            if (sessionIt != it->second.end())
-                            {
-                                sessionIt->second->send(rec.Payload);
-                            }
+                            std::cerr << "End Doc [" << uri << "].\n";
+                            Sessions.erase(it);
+                            ChildToDoc.erase(rec.Pid);
                         }
-                        else
+                    }
+                    else
+                    {
+                        std::cerr << "ERROR: Doc [" << uri << "] does not 
exist.\n";
+                    }
+                }
+            }
+            else if (rec.Dir == TraceFileRecord::Direction::Incoming)
+            {
+                auto docIt = ChildToDoc.find(rec.Pid);
+                if (docIt != ChildToDoc.end())
+                {
+                    const auto& uri = docIt->second;
+                    auto it = Sessions.find(uri);
+                    if (it != Sessions.end())
+                    {
+                        const auto sessionIt = it->second.find(rec.SessionId);
+                        if (sessionIt != it->second.end())
                         {
-                            std::cerr << "ERROR: Doc [" << uri << "] does not 
exist.\n";
+                            sessionIt->second->send(rec.Payload);
                         }
                     }
                     else
                     {
-                        std::cerr << "ERROR: Unknown PID [" << rec.Pid << "] 
maps to no active document.\n";
+                        std::cerr << "ERROR: Doc [" << uri << "] does not 
exist.\n";
                     }
                 }
+                else
+                {
+                    std::cerr << "ERROR: Unknown PID [" << rec.Pid << "] maps 
to no active document.\n";
+                }
             }
-        }
-        catch (const Poco::Exception &e)
-        {
-            std::cerr << "Failed to write data: " << e.name() <<
-                  " " << e.message() << "\n";
-            return;
+
+            epochCurrent = std::chrono::steady_clock::now();
+            epochFile = rec.TimestampNs;
         }
     }
 
diff --git a/loolwsd/TraceFile.hpp b/loolwsd/TraceFile.hpp
index 0015cbc..5e01967 100644
--- a/loolwsd/TraceFile.hpp
+++ b/loolwsd/TraceFile.hpp
@@ -92,7 +92,7 @@ class TraceFileReader
 {
 public:
     TraceFileReader(const std::string& path) :
-        _epochStart(Poco::Timestamp().epochMicroseconds()),
+        _epochStart(0),
         _stream(path),
         _index(0),
         _indexIn(-1),
@@ -101,6 +101,8 @@ public:
         readFile();
     }
 
+    Poco::Int64 getEpoch() const { return _epochStart; }
+
     TraceFileRecord getNextRecord()
     {
         if (_index < _records.size())
@@ -163,9 +165,6 @@ private:
             }
         }
 
-        _indexIn = advance(-1, TraceFileRecord::Direction::Incoming);
-        _indexOut = advance(-1, TraceFileRecord::Direction::Outgoing);
-
         if (_records.empty() ||
             _records[0].Dir != TraceFileRecord::Direction::Event ||
             _records[0].Payload.find("NewSession") != 0)
@@ -174,6 +173,11 @@ private:
                     _records.empty() ? "<empty>" : 
_records[0].Payload.c_str());
             throw std::runtime_error("Invalid trace file.");
         }
+
+        _indexIn = advance(-1, TraceFileRecord::Direction::Incoming);
+        _indexOut = advance(-1, TraceFileRecord::Direction::Outgoing);
+
+        _epochStart = _records[0].TimestampNs;
     }
 
     std::vector<std::string> split(const std::string& s, const char delim) 
const
@@ -206,7 +210,7 @@ private:
     }
 
 private:
-    const Poco::Int64 _epochStart;
+    Poco::Int64 _epochStart;
     std::ifstream _stream;
     std::vector<TraceFileRecord> _records;
     unsigned _index;
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to