Use modern UI elements to show daemons in Daemons

Summary:
Ref T3557. Slightly improves display of daemons:

  - Makes status more clear (through colors, explanatory text, icons, and explicit descriptions instead of symbols).
  - Particularly, the "wait" status is now communicated as a normal status ("waiting a moment...") with a calm blue color.
  - Uses modern responsive elements.

Test Plan: {F51232}

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T3557

Differential Revision: https://secure.phabricator.com/D6539
This commit is contained in:
epriestley 2013-07-23 12:10:30 -07:00
parent f9c6253665
commit 9a35da73ae
3 changed files with 85 additions and 100 deletions

View file

@ -61,15 +61,14 @@ final class PhabricatorDaemonConsoleController
'`status` = %s ORDER BY id DESC', '`status` = %s ORDER BY id DESC',
'run'); 'run');
$daemon_header = id(new PhabricatorHeaderView())
->setHeader(pht('Recent Daemons'));
$daemon_table = new PhabricatorDaemonLogListView(); $daemon_table = new PhabricatorDaemonLogListView();
$daemon_table->setUser($user); $daemon_table->setUser($user);
$daemon_table->setDaemonLogs($logs); $daemon_table->setDaemonLogs($logs);
$daemon_panel = new AphrontPanelView();
$daemon_panel->setHeader(pht('Active Daemons'));
$daemon_panel->appendChild($daemon_table);
$daemon_panel->setNoBackground();
$tasks = id(new PhabricatorWorkerActiveTask())->loadAllWhere( $tasks = id(new PhabricatorWorkerActiveTask())->loadAllWhere(
'leaseOwner IS NOT NULL'); 'leaseOwner IS NOT NULL');
@ -155,7 +154,8 @@ final class PhabricatorDaemonConsoleController
$nav->appendChild( $nav->appendChild(
array( array(
$completed_panel, $completed_panel,
$daemon_panel, $daemon_header,
$daemon_table,
$queued_panel, $queued_panel,
$leased_panel, $leased_panel,
)); ));

View file

@ -24,20 +24,22 @@ final class PhabricatorDaemonLogListController
$daemon_table->setUser($request->getUser()); $daemon_table->setUser($request->getUser());
$daemon_table->setDaemonLogs($logs); $daemon_table->setDaemonLogs($logs);
$daemon_panel = new AphrontPanelView(); $crumbs = $this->buildApplicationCrumbs();
$daemon_panel->setHeader(pht('All Daemons')); $crumbs->addCrumb(
$daemon_panel->appendChild($daemon_table); id(new PhabricatorCrumbView())
$daemon_panel->appendChild($pager); ->setName(pht('All Daemons')));
$daemon_panel->setNoBackground();
$nav = $this->buildSideNavView(); $nav = $this->buildSideNavView();
$nav->selectFilter('log'); $nav->selectFilter('log');
$nav->appendChild($daemon_panel); $nav->setCrumbs($crumbs);
$nav->appendChild($daemon_table);
return $this->buildApplicationPage( return $this->buildApplicationPage(
$nav, $nav,
array( array(
'title' => pht('All Daemons'), 'title' => pht('All Daemons'),
'device' => true,
'dust' => true,
)); ));
} }

View file

@ -17,112 +17,95 @@ final class PhabricatorDaemonLogListView extends AphrontView {
throw new Exception("Call setUser() before rendering!"); throw new Exception("Call setUser() before rendering!");
} }
$list = id(new PhabricatorObjectItemListView());
foreach ($this->daemonLogs as $log) { foreach ($this->daemonLogs as $log) {
$epoch = $log->getDateCreated();
// TODO: VVV Move this stuff to a Query class. VVV
$expect_heartbeat = (3 * PhutilDaemonOverseer::HEARTBEAT_WAIT);
$assume_dead = (30 * PhutilDaemonOverseer::HEARTBEAT_WAIT);
$status_running = PhabricatorDaemonLog::STATUS_RUNNING;
$status_unknown = PhabricatorDaemonLog::STATUS_UNKNOWN;
$status_wait = PhabricatorDaemonLog::STATUS_WAIT;
$status_exited = PhabricatorDaemonLog::STATUS_EXITED;
$status_dead = PhabricatorDaemonLog::STATUS_DEAD;
$status = $log->getStatus(); $status = $log->getStatus();
if ($log->getHost() == php_uname('n') && $heartbeat_timeout = $log->getDateModified() + $expect_heartbeat;
$status != PhabricatorDaemonLog::STATUS_EXITED && if ($status == $status_running && $heartbeat_timeout < time()) {
$status != PhabricatorDaemonLog::STATUS_DEAD) { $status = $status_unknown;
$pid = $log->getPID();
$is_running = PhabricatorDaemonReference::isProcessRunning($pid);
if (!$is_running) {
$guard = AphrontWriteGuard::beginScopedUnguardedWrites();
$log->setStatus(PhabricatorDaemonLog::STATUS_DEAD);
$log->save();
unset($guard);
$status = PhabricatorDaemonLog::STATUS_DEAD;
}
} }
$heartbeat_timeout = if ($status == $status_unknown && $assume_dead < time()) {
$log->getDateModified() + 3 * PhutilDaemonOverseer::HEARTBEAT_WAIT; $guard = AphrontWriteGuard::beginScopedUnguardedWrites();
if ($status == PhabricatorDaemonLog::STATUS_RUNNING && $log->setStatus($status_dead)->save();
$heartbeat_timeout < time()) { unset($guard);
$status = PhabricatorDaemonLog::STATUS_UNKNOWN;
} }
switch ($status) { if ($status != $status_running &&
case PhabricatorDaemonLog::STATUS_RUNNING:
$style = 'color: #00cc00';
$title = 'Running';
$symbol = "\xE2\x80\xA2";
break;
case PhabricatorDaemonLog::STATUS_DEAD:
$style = 'color: #cc0000';
$title = 'Died';
$symbol = "\xE2\x80\xA2";
break;
case PhabricatorDaemonLog::STATUS_EXITED:
$style = 'color: #000000';
$title = 'Exited';
$symbol = "\xE2\x80\xA2";
break;
case PhabricatorDaemonLog::STATUS_UNKNOWN:
default: // fallthrough
$style = 'color: #888888';
$title = 'Unknown';
$symbol = '?';
}
if ($status != PhabricatorDaemonLog::STATUS_RUNNING &&
$log->getDateModified() + (3 * 86400) < time()) { $log->getDateModified() + (3 * 86400) < time()) {
// Don't show rows that haven't been running for more than // Don't show rows that haven't been running for more than
// three days. We should probably prune these out of the // three days. We should probably prune these out of the
// DB similar to the code above, but we don't need to be // DB similar to the code above, but we don't need to be
// conservative and do it only on the same host // conservative and do it only on the same host
// TODO: This should not apply to the "all daemons" view!
continue; continue;
} }
$running = phutil_tag( // TODO: ^^^^ ALL THAT STUFF ^^^
'span',
array(
'style' => $style,
'title' => $title,
),
$symbol);
$rows[] = array( $id = $log->getID();
$running, $epoch = $log->getDateCreated();
$log->getDaemon(),
$log->getHost(), $item = id(new PhabricatorObjectItemView())
$log->getPID(), ->setObjectName(pht("Daemon %s", $id))
phabricator_date($epoch, $this->user), ->setHeader($log->getDaemon())
phabricator_time($epoch, $this->user), ->setHref("/daemon/log/{$id}/")
phutil_tag( ->addIcon('none', phabricator_datetime($epoch, $this->user));
'a',
array( switch ($status) {
'href' => '/daemon/log/'.$log->getID().'/', case PhabricatorDaemonLog::STATUS_RUNNING:
'class' => 'button small grey', $item->setBarColor('green');
), $item->addAttribute(pht('This daemon is running.'));
'View Log'), break;
); case PhabricatorDaemonLog::STATUS_DEAD:
$item->setBarColor('red');
$item->addAttribute(
pht(
'This daemon is lost or exited uncleanly, and is presumed '.
'dead.'));
$item->addIcon('delete', pht('Dead'));
break;
case PhabricatorDaemonLog::STATUS_EXITED:
$item->setDisabled(true);
$item->addAttribute(pht('This daemon exited cleanly.'));
$item->addIcon('enable-grey', pht('Exited'));
break;
case PhabricatorDaemonLog::STATUS_WAIT:
$item->setBarColor('blue');
$item->addAttribute(
pht(
'This daemon encountered an error recently and is waiting a '.
'moment to restart.'));
$item->addIcon('perflab-grey', pht('Waiting'));
break;
case PhabricatorDaemonLog::STATUS_UNKNOWN:
default:
$item->setBarColor('orange');
$item->addAttribute(
pht(
'This daemon has not reported its status recently. It may '.
'have exited uncleanly.'));
$item->addIcon('warning', pht('Unknown'));
break;
}
$list->addItem($item);
} }
$daemon_table = new AphrontTableView($rows); return $list;
$daemon_table->setHeaders(
array(
'',
'Daemon',
'Host',
'PID',
'Date',
'Time',
'View',
));
$daemon_table->setColumnClasses(
array(
'',
'wide wrap',
'',
'',
'',
'right',
'action',
));
return $daemon_table->render();
} }
} }