Prechádzať zdrojové kódy

Fix read/write timeouts with PhpiredisStreamConnection.

This is a regression of commit 4db0017, using stream_socket_recvfrom()
bypasses stream wrappers thus read/write timeouts handled by PHP. The
only way to make them work again is to fetch the raw socket from the
stream resource and use socket_import_stream() which is unfortunately
a PHP 5.4+ function.
Daniele Alessandri 10 rokov pred
rodič
commit
9a05d43737

+ 49 - 0
src/Connection/PhpiredisStreamConnection.php

@@ -83,6 +83,55 @@ class PhpiredisStreamConnection extends StreamConnection
         }
     }
 
+    /**
+     * Initializes a TCP stream resource.
+     *
+     * @param  ParametersInterface $parameters Initialization parameters for the connection.
+     * @return resource
+     */
+    protected function tcpStreamInitializer(ParametersInterface $parameters)
+    {
+        $uri = "tcp://{$parameters->host}:{$parameters->port}";
+        $flags = STREAM_CLIENT_CONNECT;
+        $socket = null;
+
+        if (isset($parameters->async_connect) && (bool) $parameters->async_connect) {
+            $flags |= STREAM_CLIENT_ASYNC_CONNECT;
+        }
+
+        if (isset($parameters->persistent) && (bool) $parameters->persistent) {
+            $flags |= STREAM_CLIENT_PERSISTENT;
+            $uri .= strpos($path = $parameters->path, '/') === 0 ? $path : "/$path";
+        }
+
+        $resource = @stream_socket_client($uri, $errno, $errstr, (float) $parameters->timeout, $flags);
+
+        if (!$resource) {
+            $this->onConnectionError(trim($errstr), $errno);
+        }
+
+        if (isset($parameters->read_write_timeout) && function_exists('socket_import_stream')) {
+            $rwtimeout = (float) $parameters->read_write_timeout;
+            $rwtimeout = $rwtimeout > 0 ? $rwtimeout : -1;
+
+            $timeout = array(
+                'sec'  => $timeoutSeconds = floor($rwtimeout),
+                'usec' => ($rwtimeout - $timeoutSeconds) * 1000000,
+            );
+
+            $socket = $socket ?: socket_import_stream($resource);
+            @socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, $timeout);
+            @socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, $timeout);
+        }
+
+        if (isset($parameters->tcp_nodelay) && function_exists('socket_import_stream')) {
+            $socket = $socket ?: socket_import_stream($resource);
+            socket_set_option($socket, SOL_TCP, TCP_NODELAY, (int) $parameters->tcp_nodelay);
+        }
+
+        return $resource;
+    }
+
     /**
      * Creates a new instance of the protocol reader resource.
      *

+ 2 - 2
src/Connection/StreamConnection.php

@@ -64,7 +64,7 @@ class StreamConnection extends AbstractConnection
      * @param  ParametersInterface $parameters Initialization parameters for the connection.
      * @return resource
      */
-    private function tcpStreamInitializer(ParametersInterface $parameters)
+    protected function tcpStreamInitializer(ParametersInterface $parameters)
     {
         $uri = "tcp://{$parameters->host}:{$parameters->port}";
         $flags = STREAM_CLIENT_CONNECT;
@@ -106,7 +106,7 @@ class StreamConnection extends AbstractConnection
      * @param  ParametersInterface $parameters Initialization parameters for the connection.
      * @return resource
      */
-    private function unixStreamInitializer(ParametersInterface $parameters)
+    protected function unixStreamInitializer(ParametersInterface $parameters)
     {
         $uri = "unix://{$parameters->path}";
         $flags = STREAM_CLIENT_CONNECT;