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