protected function executeChecks()
 {
     $host = PhabricatorEnv::getEnvConfig('mysql.host');
     $matches = null;
     if (preg_match('/^([^:]+):(\\d+)$/', $host, $matches)) {
         $host = $matches[1];
         $port = $matches[2];
         $this->newIssue('storage.mysql.hostport')->setName(pht('Deprecated mysql.host Format'))->setSummary(pht('Move port information from `%s` to `%s` in your config.', 'mysql.host', 'mysql.port'))->setMessage(pht('Your `%s` configuration contains a port number, but this usage ' . 'is deprecated. Instead, put the port number in `%s`.', 'mysql.host', 'mysql.port'))->addPhabricatorConfig('mysql.host')->addPhabricatorConfig('mysql.port')->addCommand(hsprintf('<tt>phabricator/ $</tt> ./bin/config set mysql.host %s', $host))->addCommand(hsprintf('<tt>phabricator/ $</tt> ./bin/config set mysql.port %s', $port));
     }
     $refs = PhabricatorDatabaseRef::queryAll();
     $refs = mpull($refs, null, 'getRefKey');
     // Test if we can connect to each database first. If we can not connect
     // to a particular database, we only raise a warning: this allows new web
     // nodes to start during a disaster, when some databases may be correctly
     // configured but not reachable.
     $connect_map = array();
     $any_connection = false;
     foreach ($refs as $ref_key => $ref) {
         $conn_raw = $ref->newManagementConnection();
         try {
             queryfx($conn_raw, 'SELECT 1');
             $database_exception = null;
             $any_connection = true;
         } catch (AphrontInvalidCredentialsQueryException $ex) {
             $database_exception = $ex;
         } catch (AphrontConnectionQueryException $ex) {
             $database_exception = $ex;
         }
         if ($database_exception) {
             $connect_map[$ref_key] = $database_exception;
             unset($refs[$ref_key]);
         }
     }
     if ($connect_map) {
         // This is only a fatal error if we could not connect to anything. If
         // possible, we still want to start if some database hosts can not be
         // reached.
         $is_fatal = !$any_connection;
         foreach ($connect_map as $ref_key => $database_exception) {
             $issue = PhabricatorSetupIssue::newDatabaseConnectionIssue($database_exception, $is_fatal);
             $this->addIssue($issue);
         }
     }
     foreach ($refs as $ref_key => $ref) {
         if ($this->executeRefChecks($ref)) {
             return;
         }
     }
 }
 private function buildClusterDatabaseStatus()
 {
     $viewer = $this->getViewer();
     $databases = PhabricatorDatabaseRef::queryAll();
     $connection_map = PhabricatorDatabaseRef::getConnectionStatusMap();
     $replica_map = PhabricatorDatabaseRef::getReplicaStatusMap();
     Javelin::initBehavior('phabricator-tooltips');
     $rows = array();
     foreach ($databases as $database) {
         $messages = array();
         if ($database->getIsMaster()) {
             $role_icon = id(new PHUIIconView())->setIcon('fa-database sky')->addSigil('has-tooltip')->setMetadata(array('tip' => pht('Master')));
         } else {
             $role_icon = id(new PHUIIconView())->setIcon('fa-download')->addSigil('has-tooltip')->setMetadata(array('tip' => pht('Replica')));
         }
         if ($database->getDisabled()) {
             $conn_icon = 'fa-times';
             $conn_color = 'grey';
             $conn_label = pht('Disabled');
         } else {
             $status = $database->getConnectionStatus();
             $info = idx($connection_map, $status, array());
             $conn_icon = idx($info, 'icon');
             $conn_color = idx($info, 'color');
             $conn_label = idx($info, 'label');
             if ($status === PhabricatorDatabaseRef::STATUS_OKAY) {
                 $latency = $database->getConnectionLatency();
                 $latency = (int) (1000000 * $latency);
                 $conn_label = pht('%s us', new PhutilNumber($latency));
             }
         }
         $connection = array(id(new PHUIIconView())->setIcon("{$conn_icon} {$conn_color}"), ' ', $conn_label);
         if ($database->getDisabled()) {
             $replica_icon = 'fa-times';
             $replica_color = 'grey';
             $replica_label = pht('Disabled');
         } else {
             $status = $database->getReplicaStatus();
             $info = idx($replica_map, $status, array());
             $replica_icon = idx($info, 'icon');
             $replica_color = idx($info, 'color');
             $replica_label = idx($info, 'label');
             if ($database->getIsMaster()) {
                 if ($status === PhabricatorDatabaseRef::REPLICATION_OKAY) {
                     $replica_icon = 'fa-database';
                 }
             } else {
                 switch ($status) {
                     case PhabricatorDatabaseRef::REPLICATION_OKAY:
                     case PhabricatorDatabaseRef::REPLICATION_SLOW:
                         $delay = $database->getReplicaDelay();
                         if ($delay) {
                             $replica_label = pht('%ss Behind', new PhutilNumber($delay));
                         } else {
                             $replica_label = pht('Up to Date');
                         }
                         break;
                 }
             }
         }
         $replication = array(id(new PHUIIconView())->setIcon("{$replica_icon} {$replica_color}"), ' ', $replica_label);
         $health = $database->getHealthRecord();
         $health_up = $health->getUpEventCount();
         $health_down = $health->getDownEventCount();
         if ($health->getIsHealthy()) {
             $health_icon = id(new PHUIIconView())->setIcon('fa-plus green');
         } else {
             $health_icon = id(new PHUIIconView())->setIcon('fa-times red');
             $messages[] = pht('UNHEALTHY: This database has failed recent health checks. Traffic ' . 'will not be sent to it until it recovers.');
         }
         $health_count = pht('%s / %s', new PhutilNumber($health_up), new PhutilNumber($health_up + $health_down));
         $health_status = array($health_icon, ' ', $health_count);
         $conn_message = $database->getConnectionMessage();
         if ($conn_message) {
             $messages[] = $conn_message;
         }
         $replica_message = $database->getReplicaMessage();
         if ($replica_message) {
             $messages[] = $replica_message;
         }
         $messages = phutil_implode_html(phutil_tag('br'), $messages);
         $rows[] = array($role_icon, $database->getHost(), $database->getPort(), $database->getUser(), $connection, $replication, $health_status, $messages);
     }
     $table = id(new AphrontTableView($rows))->setNoDataString(pht('Phabricator is not configured in cluster mode.'))->setHeaders(array(null, pht('Host'), pht('Port'), pht('User'), pht('Connection'), pht('Replication'), pht('Health'), pht('Messages')))->setColumnClasses(array(null, null, null, null, null, null, null, 'wide'));
     $doc_href = PhabricatorEnv::getDoclink('Cluster: Databases');
     $header = id(new PHUIHeaderView())->setHeader(pht('Cluster Database Status'))->addActionLink(id(new PHUIButtonView())->setIcon('fa-book')->setHref($doc_href)->setTag('a')->setText(pht('Documentation')));
     return id(new PHUIObjectBoxView())->setHeader($header)->setTable($table);
 }