/** * Create connector object * @param array $config * @return TTransport */ private static function getConnector($config) { $class = isset($config['class']) ? $config['class'] : ''; $param = isset($config['param']) ? $config['param'] : array(); switch ($class) { case 'THttpClient': if (!isset($param['host'])) { throw new Exception('Bad Thrift transport config'); } $host = $param['host']; $port = isset($param['port']) ? $param['port'] : 80; $uri = isset($param['uri']) ? $param['uri'] : ''; $scheme = isset($param['scheme']) ? $param['scheme'] : 'http'; $timeout = isset($param['timeout']) ? $param['timeout'] : null; $connector = new THttpClient($url, $port, $uri, $scheme); $connector->setTimeoutSecs($timeout); $parameters = sprintf('host = "%s", port = %d, uri = "%s", scheme = "%s", timeout = %d', $host, $port, $uri, $scheme, $timeout); break; case 'TMemoryBuffer': $buf = isset($param['buf']) ? $param['buf'] : ''; $connector = new TMemoryBuffer($buf); $parameters = sprintf('buf = "%s"', $buf); break; case 'TPhpStream': if (!isset($param['mode'])) { throw new Exception('Bad Thrift transport config'); } $mode = $param['mode']; $connector = new TPhpStream($mode); $parameters = sprintf('mode = %d', $mode); break; case 'TSocket': $host = isset($param['host']) ? $param['host'] : 'localhost'; $port = isset($param['port']) ? $param['port'] : 9090; $persist = isset($param['persist']) ? $param['persist'] : false; $send_timeout = isset($param['send_timeout']) ? $param['send_timeout'] : 100; $recv_timeout = isset($param['recv_timeout']) ? $param['recv_timeout'] : 750; $connector = new TSocket($host, $port, $persist); $connector->setSendTimeout($send_timeout); $connector->setRecvTimeout($recv_timeout); $parameters = sprintf('host = "%s", port = %d, persist = %s, send_timeout = %d, recv_timeout = %d', $host, $port, $persist ? 'true' : 'false', $send_timeout, $recv_timeout); break; case 'TSocketPool': $hosts = isset($param['hosts']) ? $param['hosts'] : array('localhost'); $ports = isset($param['ports']) ? $param['ports'] : array(9090); $persist = isset($param['persist']) ? $param['persist'] : false; $send_timeout = isset($param['send_timeout']) ? $param['send_timeout'] : 100; $recv_timeout = isset($param['recv_timeout']) ? $param['recv_timeout'] : 750; $connector = new TSocketPool($hosts, $ports, $persist); $connector->setSendTimeout($send_timeout); $connector->setRecvTimeout($recv_timeout); $parameters = sprintf('hosts = ("%s"), ports = (%d), persist = %s, send_timeout = %d, recv_timeout = %d', implode('","', $hosts), implode('","', $ports), $persist ? 'true' : 'false', $send_timeout, $recv_timeout); break; default: throw new Exception('Unknown connector: ' . $class); } sfContext::getInstance()->getLogger()->info(sprintf('{sfThriftPlugin}Create %s connector with parameters: %s', $class, $parameters)); return $connector; }
function scribe_Log_test($messages) { if (!isset($GLOBALS['SCRIBE']['SCRIBE_CLIENT_TEST'])) { try { // Set up the socket connections $scribe_servers = array('localhost'); $scribe_ports = array(1463); print "creating socket pool\n"; $sock = new TSocketPool($scribe_servers, $scribe_ports); $sock->setDebug(0); $sock->setSendTimeout(100); $sock->setRecvTimeout(250); $sock->setNumRetries(1); $sock->setRandomize(false); $sock->setAlwaysTryLast(true); $trans = new TFramedTransport($sock); $prot = new TBinaryProtocol($trans); // Create the client print "creating scribe client\n"; $scribe_client = new scribeClient($prot); // Open the transport (we rely on PHP to close it at script termination) print "opening transport\n"; $trans->open(); // save it for future calls $GLOBALS['SCRIBE']['SCRIBE_CLIENT_TEST'] = $scribe_client; } catch (Exception $x) { print "Unable to create global scribe client, received exception: {$x} \n"; return; } } else { print "using existing scribe client\n"; $scribe_client = $GLOBALS['SCRIBE']['SCRIBE_CLIENT_TEST']; } try { print "sending messages\n"; $result = $scribe_client->Log($messages); if ($result != OK) { print "Warning: Log returned {$result} \n"; } return $result; } catch (Exception $x) { print "Scribe client failed logging " . count($messages) . " messages with exception: {$x} \n"; } }
function create_scribe_client() { try { // Set up the socket connections $scribe_servers = array('localhost'); $scribe_ports = array(1463); print "creating socket pool\n"; $sock = new TSocketPool($scribe_servers, $scribe_ports); $sock->setDebug(0); $sock->setSendTimeout(1000); $sock->setRecvTimeout(2500); $sock->setNumRetries(1); $sock->setRandomize(false); $sock->setAlwaysTryLast(true); $trans = new TFramedTransport($sock); $prot = new TBinaryProtocol($trans); // Create the client print "creating scribe client\n"; $scribe_client = new scribeClient($prot); // Open the transport (we rely on PHP to close it at script termination) print "opening transport\n"; $trans->open(); } catch (Exception $x) { print "Unable to create global scribe client, received exception: {$x} \n"; return null; } return $scribe_client; }
require_once $GEN_DIR . '/ThriftTest.php'; require_once $GEN_DIR . '/ThriftTest_types.php'; echo '===============================' . "\n"; echo ' END OF SAFE ERRORS SECTION' . "\n"; echo '===============================' . "\n\n"; $host = 'localhost'; $port = 9090; if ($argc > 1) { $host = $argv[0]; } if ($argc > 2) { $host = $argv[1]; } $hosts = array('localhost'); $socket = new TSocket($host, $port); $socket = new TSocketPool($hosts, $port); $socket->setDebug(TRUE); if ($MODE == 'inline') { $transport = $socket; $testClient = new ThriftTestClient($transport); } else { $bufferedSocket = new TBufferedTransport($socket, 1024, 1024); $transport = $bufferedSocket; $protocol = new TBinaryProtocol($transport); $testClient = new ThriftTestClient($protocol); } $transport->open(); $start = microtime(true); /** * VOID TEST */
/** * Connects the socket by iterating through all the servers in the pool * and trying to find one that: * 1. is not marked down after consecutive failures * 2. can really be connected to * * @return bool false: any IP in the pool failed to connect before returning * true: no failures */ public function open() { // Check if we want order randomization if ($this->randomize_) { // warning: don't use shuffle here because it leads to uneven // load distribution $n = count($this->servers_); $s = $this->servers_; for ($i = 1; $i < $n; $i++) { $j = mt_rand(0, $i); $tmp = $s[$i]; $s[$i] = $s[$j]; $s[$j] = $tmp; } $this->servers_ = $s; } // Count servers to identify the "last" one $numServers = count($this->servers_); $has_conn_errors = false; $fail_reason = array(); // reasons of conn failures for ($i = 0; $i < $numServers; ++$i) { // host port is stored as an array list($host, $port) = $this->servers_[$i]; $failtimeKey = TSocketPool::getAPCFailtimeKey($host, $port); // Cache miss? Assume it's OK $lastFailtime = $this->apcFetch($failtimeKey); $this->apcLog("TSocketPool: host {$host}:{$port} last fail time: " . $lastFailtime); if ($lastFailtime === FALSE) { $lastFailtime = 0; } $retryIntervalPassed = FALSE; // Cache hit...make sure enough the retry interval has elapsed if ($lastFailtime > 0) { $elapsed = time() - $lastFailtime; if ($elapsed > $this->retryInterval_) { $retryIntervalPassed = TRUE; if ($this->debug_) { call_user_func($this->debugHandler_, 'TSocketPool: retryInterval ' . '(' . $this->retryInterval_ . ') ' . 'has passed for host ' . $host . ':' . $port); } } } // Only connect if not in the middle of a fail interval, OR if this // is the LAST server we are trying, just hammer away on it $isLastServer = FALSE; if ($this->alwaysTryLast_) { $isLastServer = $i == $numServers - 1; } if ($lastFailtime === 0 || $isLastServer || $lastFailtime > 0 && $retryIntervalPassed) { // Set underlying TSocket params to this one // fsockopen requires IPv6 addresses be bracet enclosed $this->host_ = $host; $this->port_ = $port; // Try up to numRetries_ connections per server for ($attempt = 0; $attempt < $this->numRetries_; $attempt++) { try { // Use the underlying TSocket open function parent::open(); // Only clear the failure counts if required to do so if ($lastFailtime > 0) { $this->apcStore($failtimeKey, 0); } // Successful connection, return now return !$has_conn_errors; } catch (TException $tx) { // Connection failed // keep the reason for the last try $errstr = $this->getErrStr(); $errno = $this->getErrNo(); if ($errstr !== null || $errno !== null) { $fail_reason[$i] = '(' . $errstr . '[' . $errno . '])'; } else { $fail_reason[$i] = '(?)'; } } } // For transient errors (like Resource temporarily unavailable), // we might want not to cache the failure. if ($this->alwaysRetryForTransientFailure_ && $this->isTransientConnectFailure($this->getErrNo())) { continue; } $has_conn_errors = $this->recordFailure($host, $port, $this->maxConsecutiveFailures_, $this->retryInterval_, $this->debug_ ? $this->debugHandler_ : null); } else { $fail_reason[$i] = '(cached-down)'; } } // Holy shit we failed them all. The system is totally ill! $error = 'TSocketPool: All hosts in pool are down. '; $hosts = array(); foreach ($this->servers_ as $i => $server) { // array(host, port) (reasons, if exist) list($host, $port) = $server; if (ip_is_valid($host)) { $host = IPAddress($host)->forURL(); } $h = $host . ':' . $port; if (isset($fail_reason[$i])) { $h .= $fail_reason[$i]; } $hosts[] = $h; } $hostlist = implode(',', $hosts); $error .= '(' . $hostlist . ')'; if ($this->debug_) { call_user_func($this->debugHandler_, $error); } throw new TTransportException($error); }
public function open() { if (\hacklib_cast_as_boolean($this->randomize_)) { $n = count($this->servers_); $s = $this->servers_; for ($i = 1; $i < $n; $i++) { $j = mt_rand(0, $i); $tmp = $s[$i]; $s[$i] = $s[$j]; $s[$j] = $tmp; } $this->servers_ = $s; } $numServers = count($this->servers_); $has_conn_errors = false; $fail_reason = array(); for ($i = 0; $i < $numServers; ++$i) { list($host, $port) = $this->servers_[$i]; $failtimeKey = TSocketPool::getAPCFailtimeKey($host, $port); $lastFailtime = (int) $this->apcFetch($failtimeKey); $this->apcLog("TSocketPool: host {$host}:{$port} last fail time: " . $lastFailtime); $retryIntervalPassed = false; if ($lastFailtime > 0) { $elapsed = time() - $lastFailtime; if ($elapsed > $this->retryInterval_) { $retryIntervalPassed = true; if (\hacklib_cast_as_boolean($this->debug_) && $this->debugHandler_ !== null) { $dh = $this->debugHandler_; $dh('TSocketPool: retryInterval ' . '(' . $this->retryInterval_ . ') ' . 'has passed for host ' . $host . ':' . $port); } } } $isLastServer = false; if (\hacklib_cast_as_boolean($this->alwaysTryLast_)) { $isLastServer = \hacklib_equals($i, $numServers - 1); } if ($lastFailtime === 0 || \hacklib_cast_as_boolean($isLastServer) || $lastFailtime > 0 && \hacklib_cast_as_boolean($retryIntervalPassed)) { $this->host_ = $host; $this->port_ = $port; for ($attempt = 0; $attempt < $this->numRetries_; $attempt++) { try { parent::open(); if ($lastFailtime > 0) { $this->apcStore($failtimeKey, 0); } return; } catch (TException $tx) { $errstr = $this->getErrStr(); $errno = $this->getErrNo(); if ($errstr !== null || $errno !== null) { $fail_reason[$i] = '(' . $errstr . '[' . $errno . '])'; } else { $fail_reason[$i] = '(?)'; } } } if (\hacklib_cast_as_boolean($this->alwaysRetryForTransientFailure_) && \hacklib_cast_as_boolean($this->isTransientConnectFailure($this->getErrNo()))) { continue; } $dh = \hacklib_cast_as_boolean($this->debug_) ? $this->debugHandler_ : null; $has_conn_errors = $this->recordFailure($host, $port, $this->maxConsecutiveFailures_, $this->retryInterval_, $dh); } else { $fail_reason[$i] = '(cached-down)'; } } $error = 'TSocketPool: All hosts in pool are down. '; $hosts = array(); foreach ($this->servers_ as $i => $server) { list($host, $port) = $server; $h = $host . ':' . $port; if (\hacklib_cast_as_boolean(array_key_exists($i, $fail_reason))) { $h .= (string) $fail_reason[$i]; } $hosts[] = $h; } $hostlist = implode(',', $hosts); $error .= '(' . $hostlist . ')'; if (\hacklib_cast_as_boolean($this->debug_) && $this->debugHandler_ !== null) { $dh = $this->debugHandler_; $dh($error); } throw new TTransportException($error); }