Esempio n. 1
0
 /**
  * Update one client, processing any commands it has sent us. We fully
  * process all commands we've received here before returning to the main
  * server loop.
  *
  * @param ArcanistHgClientChannel The client to update.
  * @param ArcanistHgServerChannel The Mercurial server.
  *
  * @task server
  */
 private function updateClient(ArcanistHgClientChannel $client, ArcanistHgServerChannel $hg)
 {
     if (!$client->update()) {
         // Client has disconnected, don't bother proceeding.
         return false;
     }
     // Read a command from the client if one is available. Note that we stop
     // updating other clients or accepting new connections while processing a
     // command, since there isn't much we can do with them until the server
     // finishes executing this command.
     $message = $client->read();
     if (!$message) {
         return true;
     }
     $this->log($client, '$ ' . $message[0] . ' ' . $message[1]);
     $t_start = microtime(true);
     // Forward the command to the server.
     $hg->write($message);
     while (true) {
         PhutilChannel::waitForAny(array($client, $hg));
         if (!$client->update() || !$hg->update()) {
             // If either the client or server has exited, bail.
             return false;
         }
         $response = $hg->read();
         if (!$response) {
             continue;
         }
         // Forward the response back to the client.
         $client->write($response);
         // If the response was on the 'r'esult channel, it indicates the end
         // of the command output. We can process the next command (if any
         // remain) or go back to accepting new connections and servicing
         // other clients.
         if ($response[0] == 'r') {
             // Update the client immediately to try to get the bytes on the wire
             // as quickly as possible. This gives us slightly more throughput.
             $client->update();
             break;
         }
     }
     // Log the elapsed time.
     $t_end = microtime(true);
     $t = 1000000 * ($t_end - $t_start);
     $this->log($client, pht('< %sus', number_format($t, 0)));
     $this->idleSince = time();
     return true;
 }