*/
var $_timeout_microseconds;
+ /**
+ * Connect timeout in seconds
+ */
+ var $_connect_timeout;
+
+ /**
+ * Number of connection attempts for each server
+ */
+ var $_connect_attempts;
+
// }}}
// }}}
// {{{ methods
$this->_timeout_seconds = 1;
$this->_timeout_microseconds = 0;
+
+ $this->_connect_timeout = 0.01;
+ $this->_connect_attempts = 3;
}
// }}}
return false;
$this->stats['get_multi']++;
-
+ $sock_keys = array();
+
foreach ($keys as $key)
{
$sock = $this->get_sock($key);
*
* @param interger $sock Socket to connect
* @param string $host Host:IP to connect to
- * @param float $timeout (optional) Timeout value, defaults to 0.25s
*
* @return boolean
* @access private
*/
- function _connect_sock (&$sock, $host, $timeout = 0.25)
+ function _connect_sock (&$sock, $host)
{
list ($ip, $port) = explode(":", $host);
- if ($this->_persistant == 1)
- {
- $sock = @pfsockopen($ip, $port, $errno, $errstr, $timeout);
- } else
- {
- $sock = @fsockopen($ip, $port, $errno, $errstr, $timeout);
+ $sock = false;
+ $timeout = $this->_connect_timeout;
+ $errno = $errstr = null;
+ for ($i = 0; !$sock && $i < $this->_connect_attempts; $i++) {
+ if ($i > 0) {
+ # Sleep until the timeout, in case it failed fast
+ $elapsed = microtime(true) - $t;
+ if ( $elapsed < $timeout ) {
+ usleep(($timeout - $elapsed) * 1e6);
+ }
+ $timeout *= 2;
+ }
+ $t = microtime(true);
+ if ($this->_persistant == 1)
+ {
+ $sock = @pfsockopen($ip, $port, $errno, $errstr, $timeout);
+ } else
+ {
+ $sock = @fsockopen($ip, $port, $errno, $errstr, $timeout);
+ }
}
-
if (!$sock) {
if ($this->_debug)
$this->_debugprint( "Error connecting to $host: $errstr\n" );
function _dead_sock ($sock)
{
$host = array_search($sock, $this->_cache_sock);
- @list ($ip, $port) = explode(":", $host);
+ @list ($ip, /* $port */) = explode(":", $host);
$this->_host_dead[$ip] = time() + 30 + intval(rand(0, 10));
$this->_host_dead[$host] = $this->_host_dead[$ip];
unset($this->_cache_sock[$host]);
stream_set_timeout($sock, 1, 0);
$line = fgets($sock);
+ $match = array();
if (!preg_match('/^(\d+)/', $line, $match))
return null;
return $match[1];
if (isset($this->_cache_sock[$host]))
return $this->_cache_sock[$host];
+ $sock = null;
$now = time();
- list ($ip, $port) = explode (":", $host);
+ list ($ip, /* $port */) = explode (":", $host);
if (isset($this->_host_dead[$host]) && $this->_host_dead[$host] > $now ||
isset($this->_host_dead[$ip]) && $this->_host_dead[$ip] > $now)
return null;