[Libreoffice-commits] online.git: loleaflet/debug loleaflet/src loolwsd/LOOLSession.cpp loolwsd/TileCache.cpp loolwsd/TileCache.hpp loolwsd/Util.cpp

Jan Holesovsky kendy at collabora.com
Tue Aug 4 11:39:58 PDT 2015


 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 527821597f0273aedb1c98710ef794c4ba439b69
Author: Jan Holesovsky <kendy at 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) + ",";
     }
 


More information about the Libreoffice-commits mailing list