[TASK] Improve result caching
authorAndreas Wolf <andreas.wolf@typo3.org>
Wed, 3 Jun 2015 20:09:06 +0000 (22:09 +0200)
committerAndreas Wolf <andreas.wolf@typo3.org>
Sun, 7 Jun 2015 19:50:15 +0000 (21:50 +0200)
This adds caching of single file information from a PROPFIND request,
effectively making getFileInfo() 100% cached at least for the backend
file list. This should bring a huge speed improvement, as the number of
server requests will be dramatically lower.

Another step could be to request more than one level of folder
information, i.e. set a depth of 2 or three for DAV requests. This would
require more careful consideration for scenarios where parts of the
response are already in cache and other parts still need to be fetched.

Classes/Dav/CachingWebDavFrontend.php
Classes/Dav/WebDavFrontend.php

index a3ff8b2..af50582 100644 (file)
@@ -52,9 +52,17 @@ class CachingWebDavFrontend extends WebDavFrontend {
 
                if (!$this->getCache()->has($cacheKey)) {
                        ++$this->cacheMisses[__FUNCTION__];
-                       // TODO also extract information on all files/folders
-                       $this->getCache()->set($cacheKey, parent::propFind($path));
+                       $this->logger->debug('propFind(): cache miss for ' . $path);
+
+                       $propFindResult = parent::propFind($path);
+
+                       $this->getCache()->set($cacheKey, $propFindResult);
+
+                       if (substr($path, -1) == '/' || strlen($path) == 0) {
+                               $this->extractFileInformationFromPropfindResult($propFindResult);
+                       }
                } else {
+                       $this->logger->debug('propFind(): cache hit for ' . $path);
                        ++$this->cacheHits[__FUNCTION__];
                }
 
@@ -86,6 +94,9 @@ class CachingWebDavFrontend extends WebDavFrontend {
        }
 
        public function getFileInfo($path) {
+               // the leading slash is already included in baseURL/basePath
+               $path = ltrim($path, '/');
+
                $cacheKey = $this->getCacheIdentifierForFileInfo($path);
                if (!$this->getCache()->has($cacheKey)) {
                        ++$this->cacheMisses[__FUNCTION__];
@@ -111,11 +122,11 @@ class CachingWebDavFrontend extends WebDavFrontend {
        /**
         * Returns the cache identifier for the raw response for a given path
         *
-        * @param string $url
+        * @param string $path
         * @return string
         */
-       protected function getCacheIdentifierForResponse($url) {
-               return 'davResponse-' . sha1($url);
+       protected function getCacheIdentifierForResponse($path) {
+               return 'davResponse-' . sha1($path);
        }
 
        /**
@@ -145,11 +156,30 @@ class CachingWebDavFrontend extends WebDavFrontend {
         * @return string
         */
        protected function getCacheIdentifierForFileInfo($path) {
-               return 'fileinfo-' . sha1($this->baseUrl . ':' . trim($path, '/') . '/');
+               return 'fileinfo-' . sha1($this->baseUrl . ':' . $path);
        }
 
        function __destruct() {
                $this->logCacheStatistics();
        }
 
+       /**
+        * @param $propFindResult
+        */
+       protected function extractFileInformationFromPropfindResult($propFindResult) {
+               $this->logger->debug('Extracting file information from request');
+               foreach ($propFindResult as $filePath => $entry) {
+                       if (substr($filePath, -1) == '/') {
+                               continue;
+                       }
+
+                       $filePath = rawurldecode($filePath);
+                       $filePath = substr($filePath, strlen($this->basePath));
+                       $cacheKey = $this->getCacheIdentifierForFileInfo($filePath);
+                       if (!$this->getCache()->has($cacheKey)) {
+                               $this->getCache()->set($cacheKey, $this->extractFileInfo($filePath, $entry));
+                       }
+               }
+       }
+
 }
index f9a524e..d3180d8 100644 (file)
@@ -23,7 +23,8 @@ use TYPO3\FalWebdav\Utility\UrlTools;
 /**
  * Utility class for doing DAV requests to the server and decoding the results into a form usable by the driver
  *
- *
+ * All identifiers within this class are relative to the DAV storage‚Äôs base path and thus have no slash at the
+ * beginning (unlike FAL identifiers, which are always prepended with a slash).
  */
 class WebDavFrontend {