+ /**
+ * Set Scan
+ * Handle this explicity due to needing the iterator passed by reference.
+ * See: https://github.com/phpredis/phpredis#sScan
+ *
+ * @param string $key
+ * @param int &$iterator
+ * @param string|null $pattern
+ * @param int|null $count
+ * @return array $res
+ */
+ public function sScan( $key, &$iterator, $pattern = null, $count = null ) {
+ return $this->tryCall( 'sScan', [ $key, &$iterator, $pattern, $count ] );
+ }
+
+ /**
+ * Hash Scan
+ * Handle this explicity due to needing the iterator passed by reference.
+ * See: https://github.com/phpredis/phpredis#hScan
+ *
+ * @param string $key
+ * @param int &$iterator
+ * @param string|null $pattern
+ * @param int|null $count
+ * @return array $res
+ */
+ public function hScan( $key, &$iterator, $pattern = null, $count = null ) {
+ return $this->tryCall( 'hScan', [ $key, &$iterator, $pattern, $count ] );
+ }
+
+ /**
+ * Sorted Set Scan
+ * Handle this explicity due to needing the iterator passed by reference.
+ * See: https://github.com/phpredis/phpredis#hScan
+ *
+ * @param string $key
+ * @param int &$iterator
+ * @param string|null $pattern
+ * @param int|null $count
+ * @return array $res
+ */
+ public function zScan( $key, &$iterator, $pattern = null, $count = null ) {
+ return $this->tryCall( 'zScan', [ $key, &$iterator, $pattern, $count ] );
+ }
+
+ /**
+ * Handle authentication errors and automatically reauthenticate.
+ *
+ * @return constant self::AUTH_NO_ERROR, self::AUTH_ERROR_TEMPORARY, or self::AUTH_ERROR_PERMANENT
+ */
+ private function checkAuthentication() {
+ if ( preg_match( '/^ERR operation not permitted\b/', $this->conn->getLastError() ) ) {
+ if ( !$this->pool->reauthenticateConnection( $this->server, $this->conn ) ) {
+ return self::AUTH_ERROR_PERMANENT;
+ }
+ $this->conn->clearLastError();
+ $this->logger->info(
+ "Used automatic re-authentication for Redis.",
+ [ 'redis_server' => $this->server ]
+ );
+ return self::AUTH_ERROR_TEMPORARY;
+ }
+ return self::AUTH_NO_ERROR;
+ }
+
+ /**
+ * Post Redis call cleanup.
+ *
+ * @return void
+ */
+ private function postCallCleanup() {
+ $this->lastError = $this->conn->getLastError() ?: $this->lastError;
+
+ // Restore original timeout in the case of blocking calls.
+ $this->pool->resetTimeout( $this->conn );