[BUGFIX] Do not serialize variables for TransientMemoryBackend 00/50600/3
authorClaus Due <claus@namelesscoder.net>
Fri, 11 Nov 2016 23:35:37 +0000 (00:35 +0100)
committerStefan Neufeind <typo3.neufeind@speedpartner.de>
Sun, 13 Nov 2016 12:59:40 +0000 (13:59 +0100)
This change switches the internal behavior of the VariableFrontend
when combined with the TransientMemoryBackend. Before this
patch the VariableFrontend was only capable of storing strings
and would serialize all variables it received, and unserialize all
variables it retrieves.

Rather than do this unnecessary serializing, a new contract is
implemented to indicate that the backend implementing the
contract is capable of storing non-string values, including
references to objects. When the VariableFrontend detects
this contract it skips the serialize/unserialize steps.

Change-Id: I255dbda2ae3791ad6325c5b4ad67c97e172e22f4
Releases: master, 7.6
Resolves: #78664
Reviewed-on: https://review.typo3.org/50600
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Philipp Gampe <philipp.gampe@typo3.org>
Tested-by: Philipp Gampe <philipp.gampe@typo3.org>
Reviewed-by: Stefan Neufeind <typo3.neufeind@speedpartner.de>
Tested-by: Stefan Neufeind <typo3.neufeind@speedpartner.de>
typo3/sysext/core/Classes/Cache/Backend/TransientBackendInterface.php [new file with mode: 0644]
typo3/sysext/core/Classes/Cache/Backend/TransientMemoryBackend.php
typo3/sysext/core/Classes/Cache/Frontend/VariableFrontend.php

diff --git a/typo3/sysext/core/Classes/Cache/Backend/TransientBackendInterface.php b/typo3/sysext/core/Classes/Cache/Backend/TransientBackendInterface.php
new file mode 100644 (file)
index 0000000..720f7f2
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+namespace TYPO3\CMS\Core\Cache\Backend;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+/**
+ * A contract for a cache backends which store variables in volatile
+ * memory and as such support receiving any variable type to store.
+ *
+ * Note: respect for this contract is up to each individual frontend.
+ * The contract can be respected for a small performance boost, but
+ * the result is marginal except for cases with huge serialized
+ * data sets.
+ *
+ * Respected by the VariableFrontend which checks if the backend
+ * has this interface, in which case it allows the backend to store
+ * the value directly without serializing it to a string, and does
+ * not attempt to unserialize the string on every get() request.
+ *
+ * @api
+ */
+interface TransientBackendInterface extends BackendInterface
+{
+}
index 32e366c..f80a323 100644 (file)
@@ -20,7 +20,7 @@ namespace TYPO3\CMS\Core\Cache\Backend;
  * This file is a backport from FLOW3
  * @api
  */
-class TransientMemoryBackend extends \TYPO3\CMS\Core\Cache\Backend\AbstractBackend implements \TYPO3\CMS\Core\Cache\Backend\TaggableBackendInterface
+class TransientMemoryBackend extends \TYPO3\CMS\Core\Cache\Backend\AbstractBackend implements TaggableBackendInterface, TransientBackendInterface
 {
     /**
      * @var array
@@ -49,9 +49,6 @@ class TransientMemoryBackend extends \TYPO3\CMS\Core\Cache\Backend\AbstractBacke
         if (!$this->cache instanceof \TYPO3\CMS\Core\Cache\Frontend\FrontendInterface) {
             throw new \TYPO3\CMS\Core\Cache\Exception('No cache frontend has been set yet via setCache().', 1238244992);
         }
-        if (!is_string($data)) {
-            throw new \TYPO3\CMS\Core\Cache\Exception\InvalidDataException('The specified data is of type "' . gettype($data) . '" but a string is expected.', 1238244993);
-        }
         $this->entries[$entryIdentifier] = $data;
         foreach ($tags as $tag) {
             $this->tagsAndEntries[$tag][$entryIdentifier] = true;
index e03628b..b79463d 100644 (file)
@@ -14,6 +14,7 @@ namespace TYPO3\CMS\Core\Cache\Frontend;
  * The TYPO3 project - inspiring people to share!
  */
 
+use TYPO3\CMS\Core\Cache\Backend\TransientBackendInterface;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
@@ -57,7 +58,10 @@ class VariableFrontend extends AbstractFrontend
                 GeneralUtility::callUserFunction($_funcRef, $params, $this);
             }
         }
-        $this->backend->set($entryIdentifier, serialize($variable), $tags, $lifetime);
+        if (!$this->backend instanceof TransientBackendInterface) {
+            $variable = serialize($variable);
+        }
+        $this->backend->set($entryIdentifier, $variable, $tags, $lifetime);
     }
 
     /**
@@ -81,7 +85,7 @@ class VariableFrontend extends AbstractFrontend
         if ($rawResult === false) {
             return false;
         } else {
-            return unserialize($rawResult);
+            return $this->backend instanceof TransientBackendInterface ? $rawResult : unserialize($rawResult);
         }
     }
 
@@ -104,7 +108,7 @@ class VariableFrontend extends AbstractFrontend
         foreach ($identifiers as $identifier) {
             $rawResult = $this->backend->get($identifier);
             if ($rawResult !== false) {
-                $entries[] = unserialize($rawResult);
+                $entries[] = $this->backend instanceof TransientBackendInterface ? $rawResult : unserialize($rawResult);
             }
         }
         return $entries;