예제 #1
0
 /**
  * Connects the socket by iterating through all the servers in the pool
  * and trying to find one that works.
  */
 public function open()
 {
     // Check if we want order randomization
     if ($this->randomize_) {
         shuffle($this->servers_);
     }
     // Count servers to identify the "last" one
     $numServers = count($this->servers_);
     for ($i = 0; $i < $numServers; ++$i) {
         // This extracts the $host and $port variables
         extract($this->servers_[$i]);
         // Check APC cache for a record of this server being down
         $failtimeKey = 'thrift_failtime:' . $host . ':' . $port . '~';
         // Cache miss? Assume it's OK
         $lastFailtime = apc_fetch($failtimeKey);
         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
             $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) {
                         apc_store($failtimeKey, 0);
                     }
                     // Successful connection, return now
                     return;
                 } catch (TException $tx) {
                     // Connection failed
                 }
             }
             // Mark failure of this host in the cache
             $consecfailsKey = 'thrift_consecfails:' . $host . ':' . $port . '~';
             // Ignore cache misses
             $consecfails = apc_fetch($consecfailsKey);
             if ($consecfails === FALSE) {
                 $consecfails = 0;
             }
             // Increment by one
             $consecfails++;
             // Log and cache this failure
             if ($consecfails >= $this->maxConsecutiveFailures_) {
                 if ($this->debug_) {
                     call_user_func($this->debugHandler_, 'TSocketPool: marking ' . $host . ':' . $port . ' as down for ' . $this->retryInterval_ . ' secs ' . 'after ' . $consecfails . ' failed attempts.');
                 }
                 // Store the failure time
                 apc_store($failtimeKey, time());
                 // Clear the count of consecutive failures
                 apc_store($consecfailsKey, 0);
             } else {
                 apc_store($consecfailsKey, $consecfails);
             }
         }
     }
     // Oh no; we failed them all. The system is totally ill!
     $error = 'TSocketPool: All hosts in pool are down. ';
     $hosts = array();
     foreach ($this->servers_ as $server) {
         $hosts[] = $server['host'] . ':' . $server['port'];
     }
     $hostlist = implode(',', $hosts);
     $error .= '(' . $hostlist . ')';
     if ($this->debug_) {
         call_user_func($this->debugHandler_, $error);
     }
     throw new TException($error);
 }
예제 #2
0
 /**
  * Implementation of accept. If not client is accepted in the given time
  *
  * @return TSocket
  */
 protected function acceptImpl()
 {
     $handle = @stream_socket_accept($this->listener_, $this->acceptTimeout_ / 1000.0);
     if (!$handle) {
         return null;
     }
     $socket = new TSocket();
     $socket->setHandle($handle);
     return $socket;
 }