[BUGFIX] Implement connection timeout option for Redis backend 99/51799/4
authorArno Schoon <arno@maxserv.com>
Thu, 23 Feb 2017 09:37:54 +0000 (10:37 +0100)
committerChristian Kuhn <lolli@schwarzbu.ch>
Tue, 28 Feb 2017 14:43:09 +0000 (15:43 +0100)
Allow an option for connectionTimeout to be set for the Redis cache backend

Resolves: #79966
Releases: master
Change-Id: I9a4d1abb07f4e199a8c1a53a6fc3de6ddf613140
Reviewed-on: https://review.typo3.org/51799
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
Reviewed-by: Josef Glatz <josef.glatz@typo3.org>
Reviewed-by: Richard Haeser <richardhaeser@gmail.com>
Tested-by: Richard Haeser <richardhaeser@gmail.com>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
typo3/sysext/core/Classes/Cache/Backend/RedisBackend.php
typo3/sysext/core/Tests/Unit/Cache/Backend/RedisBackendTest.php

index c035d7f..c431d50 100644 (file)
@@ -123,6 +123,13 @@ class RedisBackend extends AbstractBackend implements TaggableBackendInterface
     protected $compressionLevel = -1;
 
     /**
+     * limit in seconds (default is 0 meaning unlimited)
+     *
+     * @var int
+     */
+    protected $connectionTimeout = 0;
+
+    /**
      * Construct this backend
      *
      * @param string $context FLOW3's application context
@@ -148,9 +155,9 @@ class RedisBackend extends AbstractBackend implements TaggableBackendInterface
         $this->redis = new \Redis();
         try {
             if ($this->persistentConnection) {
-                $this->connected = $this->redis->pconnect($this->hostname, $this->port);
+                $this->connected = $this->redis->pconnect($this->hostname, $this->port, $this->connectionTimeout);
             } else {
-                $this->connected = $this->redis->connect($this->hostname, $this->port);
+                $this->connected = $this->redis->connect($this->hostname, $this->port, $this->connectionTimeout);
             }
         } catch (\Exception $e) {
             \TYPO3\CMS\Core\Utility\GeneralUtility::sysLog('Could not connect to redis server.', 'core', \TYPO3\CMS\Core\Utility\GeneralUtility::SYSLOG_SEVERITY_ERROR);
@@ -277,6 +284,29 @@ class RedisBackend extends AbstractBackend implements TaggableBackendInterface
     }
 
     /**
+     * Set connection timeout.
+     * This value in seconds is used as a maximum number
+     * of seconds to wait if a connection can be established.
+     *
+     * @param int $connectionTimeout limit in seconds, a value greater or equal than 0
+     * @return void
+     * @throws \InvalidArgumentException if compressionLevel parameter is not within allowed bounds
+     * @api
+     */
+    public function setConnectionTimeout($connectionTimeout)
+    {
+        if (!is_int($connectionTimeout)) {
+            throw new \InvalidArgumentException('The specified connection timeout is of type "' . gettype($connectionTimeout) . '" but an integer is expected.', 1487849315);
+        }
+
+        if ($connectionTimeout < 0) {
+            throw new \InvalidArgumentException('The specified connection timeout "' . $connectionTimeout . '" must be greater or equal than zero.', 1487849326);
+        }
+
+        $this->connectionTimeout = $connectionTimeout;
+    }
+
+    /**
      * Save data in the cache
      *
      * Scales O(1) with number of cache entries
index 11606e7..22b5139 100644 (file)
@@ -164,6 +164,28 @@ class RedisBackendTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
     /**
      * @test Functional
      */
+    public function setConnectionTimeoutThrowsExceptionIfConnectionTimeoutIsNotInteger()
+    {
+        $this->expectException(\InvalidArgumentException::class);
+        $this->expectExceptionCode(1487849315);
+
+        $this->setUpBackend(['connectionTimeout' => 'foo']);
+    }
+
+    /**
+     * @test Functional
+     */
+    public function setConnectionTimeoutThrowsExceptionIfConnectionTimeoutIsNegative()
+    {
+        $this->expectException(\InvalidArgumentException::class);
+        $this->expectExceptionCode(1487849326);
+
+        $this->setUpBackend(['connectionTimeout' => -1]);
+    }
+
+    /**
+     * @test Functional
+     */
     public function setThrowsExceptionIfIdentifierIsNotAString()
     {
         $this->expectException(\InvalidArgumentException::class);