[TASK] Optimize clearing file backend caches 12/19512/2
authorOliver Hader <oliver@typo3.org>
Wed, 28 Nov 2012 10:49:36 +0000 (11:49 +0100)
committerOliver Hader <oliver.hader@typo3.org>
Tue, 2 Apr 2013 09:32:20 +0000 (11:32 +0200)
During concurrent requests it might happen that one request
flushes a cache that is stored in the filesystem and another
different request tries to recreate the data. This will lead
to race conditions if the cached contents are large.

The idea is to move the current cache to a temporary location
and then remove it.

Change-Id: I242fdbc6ab28008363747a8076d021ebce127e17
Resolves: #43382
Releases: 6.0, 6.1
Reviewed-on: https://review.typo3.org/19512
Reviewed-by: Oliver Hader
Tested-by: Oliver Hader
typo3/sysext/core/Classes/Cache/Backend/FileBackend.php
typo3/sysext/core/Classes/Cache/Backend/SimpleFileBackend.php
typo3/sysext/core/Classes/Utility/GeneralUtility.php

index 23031f7..6729805 100644 (file)
@@ -288,8 +288,7 @@ class FileBackend extends \TYPO3\CMS\Core\Cache\Backend\SimpleFileBackend implem
         * @api
         */
        public function flush() {
-               \TYPO3\CMS\Core\Utility\GeneralUtility::rmdir($this->cacheDirectory, TRUE);
-               $this->createFinalCacheDirectory($this->cacheDirectory);
+               parent::flush();
                if ($this->frozen === TRUE) {
                        $this->frozen = FALSE;
                }
@@ -399,4 +398,4 @@ class FileBackend extends \TYPO3\CMS\Core\Cache\Backend\SimpleFileBackend implem
 }
 
 
-?>
\ No newline at end of file
+?>
index 6c7cb67..9ca7fda 100644 (file)
@@ -309,7 +309,7 @@ class SimpleFileBackend extends \TYPO3\CMS\Core\Cache\Backend\AbstractBackend im
         * @api
         */
        public function flush() {
-               \TYPO3\CMS\Core\Utility\GeneralUtility::rmdir($this->cacheDirectory, TRUE);
+               \TYPO3\CMS\Core\Utility\GeneralUtility::flushDirectory($this->cacheDirectory);
                $this->createFinalCacheDirectory($this->cacheDirectory);
        }
 
index 6cef5ab..de90c35 100644 (file)
@@ -2708,6 +2708,28 @@ Connection: close
        }
 
        /**
+        * Flushes a directory by first moving to a temporary resource, and then
+        * triggering the remove process. This way directories can be flushed faster
+        * to prevent race conditions on concurrent processes accessing the same directory.
+        *
+        * @param string $directory The directory to be renamed and flushed
+        * @return boolean Whether the action was successful
+        */
+       static public function flushDirectory($directory) {
+               $result = FALSE;
+
+               if (is_dir($directory)) {
+                       $temporaryDirectory = rtrim($directory, '/') . '.' . uniqid('remove') . '/';
+                       if (rename($directory, $temporaryDirectory)) {
+                               clearstatcache();
+                               $result = self::rmdir($temporaryDirectory, TRUE);
+                       }
+               }
+
+               return $result;
+       }
+
+       /**
         * Returns an array with the names of folders in a specific path
         * Will return 'error' (string) if there were an error with reading directory content.
         *
@@ -5015,4 +5037,4 @@ Connection: close
                echo $obContent;
        }
 }
-?>
\ No newline at end of file
+?>