loleaflet/debug/document/document_simple_example.html | 4 loleaflet/src/layer/tile/TileLayer.js | 4 loolwsd/LOOLSession.cpp | 25 +--- loolwsd/TileCache.cpp | 106 ++++++++++++------ loolwsd/TileCache.hpp | 14 ++ loolwsd/Util.cpp | 4 6 files changed, 103 insertions(+), 54 deletions(-)
New commits: commit d274cb037e426c6b1467db4682e445c84fabf657 Author: Jan Holesovsky <ke...@collabora.com> Date: Tue Aug 4 20:37:05 2015 +0200 Make the timestamps work also for non-file:// URLs. diff --git a/loleaflet/debug/document/document_simple_example.html b/loleaflet/debug/document/document_simple_example.html index 4f2fbb5..eae6cdf 100644 --- a/loleaflet/debug/document/document_simple_example.html +++ b/loleaflet/debug/document/document_simple_example.html @@ -49,7 +49,7 @@ var filePath = getParameterByName('file_path'); var host = getParameterByName('host'); var edit = getParameterByName('edit') === 'true'; - var timeStamp = getParameterByName('timestamp'); + var timestamp = getParameterByName('timestamp'); if (filePath === '') { vex.dialog.alert('Wrong file_path, usage: file_path=/path/to/doc/'); } @@ -81,7 +81,7 @@ doc: filePath, useSocket : true, edit: edit, - timeStamp: timeStamp, + timestamp: timestamp, readOnly: false }); map.addLayer(docLayer); diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js index b3aab76..e77fe32 100644 --- a/loleaflet/src/layer/tile/TileLayer.js +++ b/loleaflet/src/layer/tile/TileLayer.js @@ -100,8 +100,8 @@ L.TileLayer = L.GridLayer.extend({ } if (this.options.doc) { var msg = 'load url=' + this.options.doc; - if (this.options.timeStamp) { - msg += '?timestamp=' + this.options.timeStamp; + if (this.options.timestamp) { + msg += ' timestamp=' + this.options.timestamp; } this.sendMessage(msg); this.sendMessage('status'); diff --git a/loolwsd/LOOLSession.cpp b/loolwsd/LOOLSession.cpp index d6fa5aa..c74920f 100644 --- a/loolwsd/LOOLSession.cpp +++ b/loolwsd/LOOLSession.cpp @@ -346,16 +346,20 @@ bool MasterProcessSession::invalidateTiles(const char *buffer, int length, Strin bool MasterProcessSession::loadDocument(const char *buffer, int length, StringTokenizer& tokens) { - if (tokens.count() != 2) + if (tokens.count() < 2 || tokens.count() > 3) { sendTextFrame("error: cmd=load kind=syntax"); return false; } - if (tokens[1].find("url=") == 0) - _docURL = tokens[1].substr(strlen("url=")); - else - _docURL = tokens[1]; + std::string timestamp; + for (size_t i = 1; i < tokens.count(); ++i) + { + if (tokens[i].find("url=") == 0) + _docURL = tokens[i].substr(strlen("url=")); + else if (tokens[i].find("timestamp=") == 0) + timestamp = tokens[i].substr(strlen("timestamp=")); + } try { @@ -367,7 +371,7 @@ bool MasterProcessSession::loadDocument(const char *buffer, int length, StringTo return false; } - _tileCache.reset(new TileCache(_docURL)); + _tileCache.reset(new TileCache(_docURL, timestamp)); return true; } @@ -743,17 +747,9 @@ bool ChildProcessSession::loadDocument(const char *buffer, int length, StringTok _docURL = tokens[1]; URI aUri; - URI::QueryParameters params; try { aUri = URI(_docURL); - params = aUri.getQueryParameters(); - if ( !params.empty() && params.back().first == "timestamp" ) - { - aUri.setQuery(""); - params.pop_back(); - aUri.setQueryParameters(params); - } } catch(Poco::SyntaxException&) { @@ -779,6 +775,7 @@ bool ChildProcessSession::loadDocument(const char *buffer, int length, StringTok if ((_loKitDocument = _loKit->pClass->documentLoad(_loKit, aUri.toString().c_str())) == NULL) { sendTextFrame("error: cmd=load kind=failed"); + Application::instance().logger().information(Util::logPrefix() + "Failed to load: " + aUri.toString() + ", error is: " + _loKit->pClass->getError(_loKit)); return false; } diff --git a/loolwsd/TileCache.cpp b/loolwsd/TileCache.cpp index 2ee9da7..95bb2f5 100644 --- a/loolwsd/TileCache.cpp +++ b/loolwsd/TileCache.cpp @@ -15,6 +15,7 @@ #include <fstream> #include <iostream> #include <memory> +#include <sstream> #include <string> #include <Poco/DigestEngine.h> @@ -26,10 +27,12 @@ #include <Poco/StringTokenizer.h> #include <Poco/Timestamp.h> #include <Poco/URI.h> +#include <Poco/Util/Application.h> #include "LOOLWSD.hpp" #include "LOOLProtocol.hpp" #include "TileCache.hpp" +#include "Util.hpp" using Poco::DigestEngine; using Poco::DirectoryIterator; @@ -39,28 +42,16 @@ using Poco::StringTokenizer; using Poco::SyntaxException; using Poco::Timestamp; using Poco::URI; +using Poco::Util::Application; using namespace LOOLProtocol; -TileCache::TileCache(const std::string& docURL) : +TileCache::TileCache(const std::string& docURL, const std::string& timestamp) : _docURL(docURL), _isEditing(false), _hasUnsavedChanges(false) { - File dir(toplevelCacheDirName()); - - try - { - URI uri(_docURL); - if (uri.getScheme() == "" || - uri.getScheme() == "file") - { - setupForFile(dir, uri.getPath()); - } - } - catch (SyntaxException& e) - { - } + setup(timestamp); } std::unique_ptr<std::fstream> TileCache::lookupTile(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight) @@ -167,6 +158,9 @@ void TileCache::documentSaved() // update status _toBeRemoved.clear(); _hasUnsavedChanges = false; + + // FIXME should we take the exact time of the file for the local files? + saveLastModified(Timestamp()); } void TileCache::setEditing(bool editing) @@ -321,30 +315,78 @@ Timestamp TileCache::getLastModified() return result; } -void TileCache::setupForFile(File& cacheDir, const std::string& path) +void TileCache::saveLastModified(const Poco::Timestamp& timestamp) +{ + std::fstream modTimeFile(toplevelCacheDirName() + "/modtime.txt", std::ios::out); + modTimeFile << timestamp.raw() << std::endl; + modTimeFile.close(); +} + +void TileCache::setup(const std::string& timestamp) { - if (File(path).exists() && File(path).isFile()) + bool cleanEverything = true; + std::string filePath; + Timestamp lastModified; + + try { - if (cacheDir.exists()) + URI uri(_docURL); + if (uri.getScheme() == "" || + uri.getScheme() == "file") { - if (getLastModified() != File(path).getLastModified()) - { - // document changed externally, clean up everything - cacheDir.remove(true); - } - else + filePath = uri.getPath(); + } + } + catch (SyntaxException& e) + { + } + + if (!filePath.empty() && File(filePath).exists() && File(filePath).isFile()) + { + // for files, always use the real path + lastModified = File(filePath).getLastModified(); + cleanEverything = (getLastModified() < lastModified); + } + else if (!timestamp.empty()) + { + // otherwise try the timestamp provided by the caller + Timestamp::TimeVal lastTimeVal; + std::istringstream(timestamp) >> lastTimeVal; + lastModified = lastTimeVal; + Application::instance().logger().information(Util::logPrefix() + "Timestamp provided externally: " + timestamp); + + cleanEverything = (getLastModified() < Timestamp(lastModified)); + } + else + { + // when no timestamp, and non-file, assume 'now' + lastModified = Timestamp(); + } + + File cacheDir(toplevelCacheDirName()); + if (cacheDir.exists()) + { + if (cleanEverything) + { + // document changed externally, clean up everything + cacheDir.remove(true); + Application::instance().logger().information(Util::logPrefix() + "Completely cleared cache: " + toplevelCacheDirName()); + } + else + { + // remove only the Editing cache + File editingCacheDir(cacheDirName(true)); + if (editingCacheDir.exists()) { - // remove only the Editing cache - File editingCacheDir(cacheDirName(true)); - if (editingCacheDir.exists()) - editingCacheDir.remove(true); + editingCacheDir.remove(true); + Application::instance().logger().information(Util::logPrefix() + "Cleared the editing cache: " + cacheDirName(true)); } } - cacheDir.createDirectories(); - std::fstream modTimeFile(cacheDir.path() + "/modtime.txt", std::ios::out); - modTimeFile << File(path).getLastModified().raw() << std::endl; - modTimeFile.close(); } + + cacheDir.createDirectories(); + + saveLastModified(lastModified); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/loolwsd/TileCache.hpp b/loolwsd/TileCache.hpp index bcc6416..ca3a51f 100644 --- a/loolwsd/TileCache.hpp +++ b/loolwsd/TileCache.hpp @@ -30,7 +30,10 @@ The editing cache is cleared on startup, and copied to the persistent on each sa class TileCache { public: - TileCache(const std::string& docURL); + /// When the docURL is a non-file:// url, the timestamp has to be provided by the caller. + /// For file:// url's, it's ignored. + /// When it is missing for non-file:// url, it is assumed the document must be read, and no cached value used. + TileCache(const std::string& docURL, const std::string& timestamp); std::unique_ptr<std::fstream> lookupTile(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight); void saveTile(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight, const char *data, size_t size); @@ -63,8 +66,15 @@ private: /// Extract location from fileName, and check if it intersects with [x, y, width, height]. bool intersectsTile(std::string& fileName, int part, int x, int y, int width, int height); + /// Load the timestamp from modtime.txt. Poco::Timestamp getLastModified(); - void setupForFile(Poco::File& cacheDir, const std::string& path); + + /// Store the timestamp to modtime.txt. + void saveLastModified(const Poco::Timestamp& timestamp); + + /// Create or cleanup the cache directory. + /// For non-file:// protocols, the timestamp has to be provided externally. + void setup(const std::string& timestamp); const std::string& _docURL; diff --git a/loolwsd/Util.cpp b/loolwsd/Util.cpp index 85bae00..b6e0b64 100644 --- a/loolwsd/Util.cpp +++ b/loolwsd/Util.cpp @@ -51,8 +51,8 @@ namespace Util std::string logPrefix() { - Poco::Timestamp timeStamp; - Poco::Int64 now = timeStamp.epochMicroseconds(); + Poco::Timestamp timestamp; + Poco::Int64 now = timestamp.epochMicroseconds(); return std::to_string(Poco::Process::id()) + "," + (Poco::Thread::current() ? std::to_string(Poco::Thread::current()->id()) : "0") + "," + std::to_string(now / 1000) + ","; } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits