jenkins-bot has submitted this change and it was merged.

Change subject: Add support for curl connections pools in hhvm
......................................................................


Add support for curl connections pools in hhvm

Utilizes curl_init_pooled available in hhvm >= 3.9.0 to support
connection pooling. This is particularly important for use cases
that involve https, to avoid the costly setup time for tls.

Change-Id: I3a05b5fcaae5d69d1bd759cfafe447f4252dc08a
---
M autoload.php
M includes/Connection.php
A includes/Elastica/PooledHttp.php
A includes/Elastica/PooledHttps.php
4 files changed, 117 insertions(+), 2 deletions(-)

Approvals:
  Smalyshev: Looks good to me, approved
  Cindy-the-browser-test-bot: Looks good to me, but someone else must approve
  jenkins-bot: Verified



diff --git a/autoload.php b/autoload.php
index 86fba2f..d400f3f 100644
--- a/autoload.php
+++ b/autoload.php
@@ -30,6 +30,8 @@
        'CirrusSearch\\Connection' => __DIR__ . '/includes/Connection.php',
        'CirrusSearch\\DataSender' => __DIR__ . '/includes/DataSender.php',
        'CirrusSearch\\Dump' => __DIR__ . '/includes/Dump.php',
+       'CirrusSearch\\Elastica\\PooledHttp' => __DIR__ . 
'/includes/Elastica/PooledHttp.php',
+       'CirrusSearch\\Elastica\\PooledHttps' => __DIR__ . 
'/includes/Elastica/PooledHttps.php',
        'CirrusSearch\\ElasticsearchIntermediary' => __DIR__ . 
'/includes/ElasticsearchIntermediary.php',
        'CirrusSearch\\Extra\\Filter\\IdHashMod' => __DIR__ . 
'/includes/Extra/Filter/IdHashMod.php',
        'CirrusSearch\\Extra\\Filter\\SourceRegex' => __DIR__ . 
'/includes/Extra/Filter/SourceRegex.php',
diff --git a/includes/Connection.php b/includes/Connection.php
index d4a3f18..fca8123 100644
--- a/includes/Connection.php
+++ b/includes/Connection.php
@@ -154,9 +154,23 @@
                // will work as expected.
                if ( $this->config->has( 'CirrusSearchServers' ) ) {
                        return $this->config->get( 'CirrusSearchServers' );
-               } else {
-                       return $this->config->getElement( 
'CirrusSearchClusters', $this->cluster );
                }
+               $config = $this->config->getElement( 'CirrusSearchClusters', 
$this->cluster );
+
+               // Elastica will only create transports from within it's own
+               // namespace. To use the CirrusSearch PooledHttp(s) this
+               // clause is necessary.
+               foreach ( $config as $idx => $server ) {
+                       if (
+                               isset( $server['transport'] ) &&
+                               class_exists( $server['transport'] )
+                       ) {
+                               $transportClass = $server['transport'];
+                               $config[$idx]['transport'] = new 
$transportClass;
+                       }
+               }
+
+               return $config;
        }
 
        /**
diff --git a/includes/Elastica/PooledHttp.php b/includes/Elastica/PooledHttp.php
new file mode 100644
index 0000000..766e611
--- /dev/null
+++ b/includes/Elastica/PooledHttp.php
@@ -0,0 +1,84 @@
+<?php
+
+namespace CirrusSearch\Elastica;
+
+use Elastica\Transport\Http;
+use MediaWiki\Logger\LoggerFactory;
+
+/**
+ * Implements cross-request connection pooling via hhvm's built in
+ * curl_init_pooled. To utilize this transport $wgCirrusSearchClusters should
+ * be configured as follows:
+ *
+ *  $wgCirrusSearchClusters = array(
+ *    'default' => array(
+ *      'transport' => 'CirrusSearch\Elastica\PooledHttp',
+ *      'port' => 12345,
+ *      'host' => 'my.host.name',
+ *      'config' => array( 'pool' => 'cirrus' ),
+ *    )
+ *  );
+ *
+ * Additionally hhvm needs the following configuration in its php.ini:
+ *
+ *  curl.namedPools = cirrus
+ *
+ * Other optional pool parameters (also in php.ini) and their defaults:
+ *
+ *  curl.namedPools.cirrus.size = 5
+ *  curl.namedPools.cirrus.reuseLimit = 100
+ *  curl.namedPools.cirrus.connGetTimeout = 5000
+ *
+ * For connection pooling to work optimally you will want to configure a pool
+ * for each host you connect to. This means using a different pool for each
+ * cluster, and using some sort of load balancer that allows to connect to
+ * your entire cluster using a single ip or domain name.
+ */
+class PooledHttp extends Http {
+
+       /**
+        * Map from pool name to active connection
+        */
+       private $_curlPoolConnections = array();
+
+       /**
+        * @param bool $persistent
+        * @return resource Curl handle
+        */
+       protected function _getConnection( $persistent = true ) {
+               $conn = $this->getConnection();
+               if ( !$persistent ) {
+                       return parent::_getConnection( $persistent );
+               }
+
+               $ch = null;
+               if ( !$conn->hasConfig( 'pool' ) ) {
+                       LoggerFactory::getInstance( 'CirrusSearch' )->warning(
+                               "Elastica connection pool cannot init: missing 
pool name in connection config"
+                       );
+               } elseif ( !function_exists( 'curl_init_pooled' ) ) {
+                       LoggerFactory::getInstance( 'CirrusSearch' )->warning(
+                               "Elastica connection pool cannot init: missing 
curl_init_pooled method. Are you using hhvm >= 3.9.0?"
+                       );
+               } else {
+                       $pool = $conn->getConfig( 'pool' );
+                       // Note that if the connection pool is full this will 
block
+                       // up to curl.namedPools.$pool.connGetTimeout ms, 
defaulting
+                       // to 5000. If the timeout is reached hhvm will raise a 
fatal
+                       // error.
+                       $ch = curl_init_pooled( $pool );
+                       if ( $ch === null ) {
+                               LoggerFactory::getInstance( 'CirrusSearch' 
)->warning(
+                                       "Elastic connection pool cannot init: 
Unknown pool {pool}. Did you configure curl.namedPools?",
+                                       array( 'pool' => $pool )
+                               );
+                       }
+               }
+
+               if ( $ch === null ) {
+                       return parent::_getConnection( $persistent );
+               }
+
+               return $ch;
+       }
+}
diff --git a/includes/Elastica/PooledHttps.php 
b/includes/Elastica/PooledHttps.php
new file mode 100644
index 0000000..2d79153
--- /dev/null
+++ b/includes/Elastica/PooledHttps.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace CirrusSearch\Elastica;
+
+/**
+ * Connection pooling for https
+ */
+class PooledHttps extends PooledHttp {
+       /**
+        * Https scheme.
+        *
+        * @var string https scheme
+        */
+       protected $_scheme = 'https';
+}

-- 
To view, visit https://gerrit.wikimedia.org/r/277907
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I3a05b5fcaae5d69d1bd759cfafe447f4252dc08a
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/CirrusSearch
Gerrit-Branch: master
Gerrit-Owner: EBernhardson <[email protected]>
Gerrit-Reviewer: Cindy-the-browser-test-bot <[email protected]>
Gerrit-Reviewer: DCausse <[email protected]>
Gerrit-Reviewer: Gehel <[email protected]>
Gerrit-Reviewer: Manybubbles <[email protected]>
Gerrit-Reviewer: Smalyshev <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to