%PDF- %PDF-
Direktori : /www/varak.net/wiki.varak.net/extensions/CirrusSearch/includes/Elastica/ |
Current File : /www/varak.net/wiki.varak.net/extensions/CirrusSearch/includes/Elastica/PooledHttp.php |
<?php namespace CirrusSearch\Elastica; use Elastica\Transport\Http; use MediaWiki\Logger\LoggerFactory; use MediaWiki\MediaWikiServices; use RequestContext; /** * 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 { /** * @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. $start = microtime( true ); $ch = curl_init_pooled( $pool ); $this->reportTiming( microtime( true ) - $start ); if ( $ch === null ) { LoggerFactory::getInstance( 'CirrusSearch' )->warning( "Elastic connection pool cannot init: Unknown pool {pool}. Did you configure curl.namedPools?", [ 'pool' => $pool ] ); } } if ( $ch === null ) { return parent::_getConnection( $persistent ); } return $ch; } /** * @param float $tookS The number of seconds taken to get the pooled handle */ protected function reportTiming( $tookS ) { // Should this in some way collect stats about requests that take longer than normal, // or just allow standard p95 or p99 to collect them? With thousands of requests per // second i wonder if a couple servers having issues with their pools will by lost in // the noise. Another option could be recording per-server stats and including gethostname() // in the key? MediaWikiServices::getInstance()->getStatsdDataFactory()->timing( 'CirrusSearch.connectionPool.initMs', intval( 1000 * $tookS ) ); } }