Skip to content

Commit

Permalink
Adding a way to limit the maximum number of curl handle connection re…
Browse files Browse the repository at this point in the history
…uses per host.
  • Loading branch information
mtdowling committed Sep 7, 2011
1 parent 7978cc1 commit 83ec9f3
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 5 deletions.
27 changes: 27 additions & 0 deletions Curl/CurlFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ class CurlFactory implements CurlFactoryInterface
*/
protected $maxIdleTime = -1;

/**
* Array of host as the key and maximum number of handles reuses
* as the value per host.
*
* @var array
*/
protected $maxConnectionReusesPerHost = array();

/**
* Singleton method to get a single instance of the default CurlFactory.
*
Expand Down Expand Up @@ -126,6 +134,21 @@ public function setMaxIdleForHost($host, $total)
return $this;
}

/**
* Set the maximum number of connection reuses for a specific host/port
*
* @param string $host Host to specify including port
* @param int $max Max number of connection reuses per handle
*
* @return CurlFactory
*/
public function setMaxConnectionReusesForHost($host, $max)
{
$this->maxConnectionReusesPerHost[$host] = $max;

return $this;
}

/**
* Get a cURL handle for an HTTP request
*
Expand Down Expand Up @@ -288,6 +311,10 @@ protected function createHandle(RequestInterface $request)
// Apply the options to the cURL handle.
curl_setopt_array($handle, $options);
$h = new CurlHandle($handle, $options);
$hostKey = $request->getHost() . ':' . $request->getPort();
if (isset($this->maxConnectionReusesPerHost[$hostKey])) {
$h->setMaxReuses($this->maxConnectionReusesPerHost[$hostKey]);
}
$this->handles[] = $h;

return $h;
Expand Down
47 changes: 42 additions & 5 deletions Curl/CurlHandle.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ class CurlHandle
*/
protected $stderr;

/**
* @var int Number of times the handle has been (re)used
*/
protected $useCount = 0;

/**
* @var int
*/
protected $maxReuses;

/**
* @var array Statically cached array of cURL options that pollute handles
*/
Expand Down Expand Up @@ -153,6 +163,30 @@ public function getInfo($option = null)
: @curl_getinfo($this->handle);
}

/**
* Set the maximum number of times a handle can be reused
*
* @param int $max Maximum reuse count
*
* @return CurlHandle
*/
public function setMaxReuses($max)
{
$this->maxReuses = $max;

return $this;
}

/**
* Get the number of times the handle has been used
*
* @return int
*/
public function getUseCount()
{
return $this->useCount;
}

/**
* Get the stderr output
*
Expand Down Expand Up @@ -210,11 +244,14 @@ public function checkout(RequestInterface $request)
*/
public function unlock()
{
if ($this->isAvailable() && ($this->hasProblematicOption() || ($this->owner
&& ($this->owner->getHeader('Connection', null, true) == 'close'
|| ($this->owner->getResponse() && $this->owner->getResponse()->getHeader('Connection', null, true) == 'close'))))) {
curl_close($this->handle);
$this->handle = null;
if ($this->isAvailable()) {
$this->useCount++;
if ((null !== $this->maxReuses && $this->useCount > $this->maxReuses) ||
($this->hasProblematicOption() || ($this->owner && ($this->owner->getHeader('Connection', null, true) == 'close' || ($this->owner->getResponse() && $this->owner->getResponse()->getHeader('Connection', null, true) == 'close'))))) {
curl_close($this->handle);
$this->handle = null;
$this->useCount = 0;
}
}

$this->owner = null;
Expand Down

0 comments on commit 83ec9f3

Please sign in to comment.