From beaf0bb89888098e75e09cdd2ec80670977b9d11 Mon Sep 17 00:00:00 2001 From: epriestley Date: Tue, 22 Jan 2013 12:14:33 -0800 Subject: [PATCH] Improve Daemon console UI Summary: Makes various fixes to the Daemon console UI: - Removes timeline, timeline cursors, and timeline-related controllers. This abstraction is all but dead and just waiting on an eventual cleanup effort with Facebook (see T2003). There's no need to inspect or debug it anymore. - Instead of showing the 15 most recently launched non-exited daemons, show all the running daemons. With the old rule, "dead" daemons tended to build up at the bottom of the list -- e.g., secure.phabricator.com shows the 7 active daemons, then 8 dead daemons from as far back as Aug 2012. Showing running daemons is far more useful. - Simplify the two "Running Daemons" and "All Daemons" subviews into one "All Daemons" subview. The main console now has "running daemons", effectively. - Create a "Recently completed tasks" view, which shows how many tasks of each task class have completed in the last 15 minutes and how long they took on average. Understanding how quickly tasks are completing is one of the most common uses of the daemon console, and it's currently almost useless for that. Now that we archive tasks, we can show this information in an easily digestable form. - Partially modernize all of the remaining views. Test Plan: Looked at daemon console. Reviewers: btrahan, chad, vrana Reviewed By: btrahan CC: aran Maniphest Tasks: T2372, T2003 Differential Revision: https://secure.phabricator.com/D4573 --- src/__phutil_library_map__.php | 4 - .../PhabricatorApplicationDaemons.php | 7 +- ...PhabricatorDaemonCombinedLogController.php | 1 + .../PhabricatorDaemonConsoleController.php | 94 ++++++++++++------- .../PhabricatorDaemonController.php | 6 +- .../PhabricatorDaemonLogListController.php | 16 +--- ...ricatorDaemonTimelineConsoleController.php | 55 ----------- ...abricatorDaemonTimelineEventController.php | 68 -------------- 8 files changed, 68 insertions(+), 183 deletions(-) delete mode 100644 src/applications/daemon/controller/PhabricatorDaemonTimelineConsoleController.php delete mode 100644 src/applications/daemon/controller/PhabricatorDaemonTimelineEventController.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index f6211c3ff2..02897851c8 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -757,8 +757,6 @@ phutil_register_library_map(array( 'PhabricatorDaemonLogListView' => 'applications/daemon/view/PhabricatorDaemonLogListView.php', 'PhabricatorDaemonLogViewController' => 'applications/daemon/controller/PhabricatorDaemonLogViewController.php', 'PhabricatorDaemonReference' => 'infrastructure/daemon/control/PhabricatorDaemonReference.php', - 'PhabricatorDaemonTimelineConsoleController' => 'applications/daemon/controller/PhabricatorDaemonTimelineConsoleController.php', - 'PhabricatorDaemonTimelineEventController' => 'applications/daemon/controller/PhabricatorDaemonTimelineEventController.php', 'PhabricatorDefaultFileStorageEngineSelector' => 'applications/files/engineselector/PhabricatorDefaultFileStorageEngineSelector.php', 'PhabricatorDefaultSearchEngineSelector' => 'applications/search/selector/PhabricatorDefaultSearchEngineSelector.php', 'PhabricatorDeveloperConfigOptions' => 'applications/config/option/PhabricatorDeveloperConfigOptions.php', @@ -2159,8 +2157,6 @@ phutil_register_library_map(array( 'PhabricatorDaemonLogListController' => 'PhabricatorDaemonController', 'PhabricatorDaemonLogListView' => 'AphrontView', 'PhabricatorDaemonLogViewController' => 'PhabricatorDaemonController', - 'PhabricatorDaemonTimelineConsoleController' => 'PhabricatorDaemonController', - 'PhabricatorDaemonTimelineEventController' => 'PhabricatorDaemonController', 'PhabricatorDefaultFileStorageEngineSelector' => 'PhabricatorFileStorageEngineSelector', 'PhabricatorDefaultSearchEngineSelector' => 'PhabricatorSearchEngineSelector', 'PhabricatorDeveloperConfigOptions' => 'PhabricatorApplicationConfigOptions', diff --git a/src/applications/daemon/application/PhabricatorApplicationDaemons.php b/src/applications/daemon/application/PhabricatorApplicationDaemons.php index f4abf1c985..4d02d15680 100644 --- a/src/applications/daemon/application/PhabricatorApplicationDaemons.php +++ b/src/applications/daemon/application/PhabricatorApplicationDaemons.php @@ -29,18 +29,15 @@ final class PhabricatorApplicationDaemons extends PhabricatorApplication { public function getRoutes() { return array( '/daemon/' => array( + '' => 'PhabricatorDaemonConsoleController', 'task/(?P[1-9]\d*)/' => 'PhabricatorWorkerTaskDetailController', 'task/(?P[1-9]\d*)/(?P[^/]+)/' => 'PhabricatorWorkerTaskUpdateController', 'log/' => array( - '(?Prunning/)?' => 'PhabricatorDaemonLogListController', + '' => 'PhabricatorDaemonLogListController', 'combined/' => 'PhabricatorDaemonCombinedLogController', '(?P[1-9]\d*)/' => 'PhabricatorDaemonLogViewController', ), - 'timeline/' => 'PhabricatorDaemonTimelineConsoleController', - 'timeline/(?P[1-9]\d*)/' - => 'PhabricatorDaemonTimelineEventController', - '' => 'PhabricatorDaemonConsoleController', ), ); } diff --git a/src/applications/daemon/controller/PhabricatorDaemonCombinedLogController.php b/src/applications/daemon/controller/PhabricatorDaemonCombinedLogController.php index 35a9a54743..8abc5b9c50 100644 --- a/src/applications/daemon/controller/PhabricatorDaemonCombinedLogController.php +++ b/src/applications/daemon/controller/PhabricatorDaemonCombinedLogController.php @@ -28,6 +28,7 @@ final class PhabricatorDaemonCombinedLogController $log_panel->setHeader('Combined Daemon Logs'); $log_panel->appendChild($event_view); $log_panel->appendChild($pager); + $log_panel->setNoBackground(); $nav = $this->buildSideNavView(); $nav->selectFilter('log/combined'); diff --git a/src/applications/daemon/controller/PhabricatorDaemonConsoleController.php b/src/applications/daemon/controller/PhabricatorDaemonConsoleController.php index c40b1c4e68..da5e439979 100644 --- a/src/applications/daemon/controller/PhabricatorDaemonConsoleController.php +++ b/src/applications/daemon/controller/PhabricatorDaemonConsoleController.php @@ -4,19 +4,71 @@ final class PhabricatorDaemonConsoleController extends PhabricatorDaemonController { public function processRequest() { - $logs = id(new PhabricatorDaemonLog())->loadAllWhere( - '`status` != %s ORDER BY id DESC LIMIT 15', 'exit'); - $request = $this->getRequest(); $user = $request->getUser(); + $completed = id(new PhabricatorWorkerArchiveTask())->loadAllWhere( + 'dateModified > %d', + time() - (60 * 15)); + + $completed_info = array(); + foreach ($completed as $completed_task) { + $class = $completed_task->getTaskClass(); + if (empty($completed_info[$class])) { + $completed_info[$class] = array( + 'n' => 0, + 'duration' => 0, + ); + } + $completed_info[$class]['n']++; + $duration = $completed_task->getDuration(); + $completed_info[$class]['duration'] += $duration; + } + + $completed_info = isort($completed_info, 'n'); + + $rows = array(); + foreach ($completed_info as $class => $info) { + $rows[] = array( + phutil_escape_html($class), + number_format($info['n']), + number_format((int)($info['duration'] / $info['n'])).' us', + ); + } + + $completed_table = new AphrontTableView($rows); + $completed_table->setNoDataString( + pht('No tasks have completed in the last 15 minutes.')); + $completed_table->setHeaders( + array( + pht('Class'), + pht('Count'), + pht('Avg'), + )); + $completed_table->setColumnClasses( + array( + 'wide', + 'n', + 'n', + )); + + $completed_panel = new AphrontPanelView(); + $completed_panel->setHeader(pht('Recently Completed Tasks (15m)')); + $completed_panel->appendChild($completed_table); + $completed_panel->setNoBackground(); + + $logs = id(new PhabricatorDaemonLog())->loadAllWhere( + '`status` = %s ORDER BY id DESC', + 'run'); + $daemon_table = new PhabricatorDaemonLogListView(); $daemon_table->setUser($user); $daemon_table->setDaemonLogs($logs); $daemon_panel = new AphrontPanelView(); - $daemon_panel->setHeader('Recently Launched Daemons'); + $daemon_panel->setHeader('Active Daemons'); $daemon_panel->appendChild($daemon_table); + $daemon_panel->setNoBackground(); $tasks = id(new PhabricatorWorkerActiveTask())->loadAllWhere( 'leaseOwner IS NOT NULL'); @@ -63,6 +115,7 @@ final class PhabricatorDaemonConsoleController $leased_panel = new AphrontPanelView(); $leased_panel->setHeader('Leased Tasks'); $leased_panel->appendChild($leased_table); + $leased_panel->setNoBackground(); $task_table = new PhabricatorWorkerActiveTask(); $queued = queryfx_all( @@ -95,41 +148,14 @@ final class PhabricatorDaemonConsoleController $queued_panel = new AphrontPanelView(); $queued_panel->setHeader('Queued Tasks'); $queued_panel->appendChild($queued_table); - - $cursors = id(new PhabricatorTimelineCursor()) - ->loadAll(); - - $rows = array(); - foreach ($cursors as $cursor) { - $rows[] = array( - phutil_escape_html($cursor->getName()), - number_format($cursor->getPosition()), - ); - } - - $cursor_table = new AphrontTableView($rows); - $cursor_table->setHeaders( - array( - 'Name', - 'Position', - )); - $cursor_table->setColumnClasses( - array( - 'wide', - 'n', - )); - $cursor_table->setNoDataString('No timeline cursors exist.'); - - $cursor_panel = new AphrontPanelView(); - $cursor_panel->setHeader('Timeline Cursors'); - $cursor_panel->appendChild($cursor_table); + $queued_panel->setNoBackground(); $nav = $this->buildSideNavView(); - $nav->selectFilter(''); + $nav->selectFilter('/'); $nav->appendChild( array( + $completed_panel, $daemon_panel, - $cursor_panel, $queued_panel, $leased_panel, )); diff --git a/src/applications/daemon/controller/PhabricatorDaemonController.php b/src/applications/daemon/controller/PhabricatorDaemonController.php index eb60cbf14d..d907aa0567 100644 --- a/src/applications/daemon/controller/PhabricatorDaemonController.php +++ b/src/applications/daemon/controller/PhabricatorDaemonController.php @@ -7,14 +7,10 @@ abstract class PhabricatorDaemonController extends PhabricatorController { $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); $nav->addLabel('Daemons'); - $nav->addFilter('', 'Console', $this->getApplicationURI()); - $nav->addFilter('log/running', 'Running Daemons'); + $nav->addFilter('/', 'Console'); $nav->addFilter('log', 'All Daemons'); $nav->addFilter('log/combined', 'Combined Log'); - $nav->addLabel('Event Timeline'); - $nav->addFilter('timeline', 'Timeline'); - return $nav; } diff --git a/src/applications/daemon/controller/PhabricatorDaemonLogListController.php b/src/applications/daemon/controller/PhabricatorDaemonLogListController.php index 9802eef317..ba6018f7bc 100644 --- a/src/applications/daemon/controller/PhabricatorDaemonLogListController.php +++ b/src/applications/daemon/controller/PhabricatorDaemonLogListController.php @@ -3,12 +3,6 @@ final class PhabricatorDaemonLogListController extends PhabricatorDaemonController { - private $running; - - public function willProcessRequest(array $data) { - $this->running = !empty($data['running']); - } - public function processRequest() { $request = $this->getRequest(); @@ -16,9 +10,6 @@ final class PhabricatorDaemonLogListController $pager->setOffset($request->getInt('page')); $clause = '1 = 1'; - if ($this->running) { - $clause = "`status` != 'exit'"; - } $logs = id(new PhabricatorDaemonLog())->loadAllWhere( '%Q ORDER BY id DESC LIMIT %d, %d', @@ -34,18 +25,19 @@ final class PhabricatorDaemonLogListController $daemon_table->setDaemonLogs($logs); $daemon_panel = new AphrontPanelView(); - $daemon_panel->setHeader('Launched Daemons'); + $daemon_panel->setHeader('All Daemons'); $daemon_panel->appendChild($daemon_table); $daemon_panel->appendChild($pager); + $daemon_panel->setNoBackground(); $nav = $this->buildSideNavView(); - $nav->selectFilter($this->running ? 'log/running' : 'log'); + $nav->selectFilter('log'); $nav->appendChild($daemon_panel); return $this->buildApplicationPage( $nav, array( - 'title' => $this->running ? 'Running Daemons' : 'All Daemons', + 'title' => 'All Daemons', )); } diff --git a/src/applications/daemon/controller/PhabricatorDaemonTimelineConsoleController.php b/src/applications/daemon/controller/PhabricatorDaemonTimelineConsoleController.php deleted file mode 100644 index 0c5f711194..0000000000 --- a/src/applications/daemon/controller/PhabricatorDaemonTimelineConsoleController.php +++ /dev/null @@ -1,55 +0,0 @@ -establishConnection('r'), - 'SELECT id, type FROM %T ORDER BY id DESC LIMIT 100', - $timeline_table->getTableName()); - - $rows = array(); - foreach ($events as $event) { - $rows[] = array( - phutil_render_tag( - 'a', - array( - 'href' => '/daemon/timeline/'.$event['id'].'/', - ), - $event['id']), - phutil_escape_html($event['type']), - ); - } - - $event_table = new AphrontTableView($rows); - $event_table->setHeaders( - array( - 'ID', - 'Type', - )); - $event_table->setColumnClasses( - array( - null, - 'wide', - )); - - $event_panel = new AphrontPanelView(); - $event_panel->setHeader('Timeline Events'); - $event_panel->appendChild($event_table); - - $nav = $this->buildSideNavView(); - $nav->selectFilter('timeline'); - $nav->appendChild($event_panel); - - return $this->buildApplicationPage( - $nav, - array( - 'title' => 'Timeline', - )); - } - -} diff --git a/src/applications/daemon/controller/PhabricatorDaemonTimelineEventController.php b/src/applications/daemon/controller/PhabricatorDaemonTimelineEventController.php deleted file mode 100644 index 25c72de011..0000000000 --- a/src/applications/daemon/controller/PhabricatorDaemonTimelineEventController.php +++ /dev/null @@ -1,68 +0,0 @@ -id = $data['id']; - } - - public function processRequest() { - $event = id(new PhabricatorTimelineEvent('NULL'))->load($this->id); - if (!$event) { - return new Aphront404Response(); - } - - $request = $this->getRequest(); - $user = $request->getUser(); - - if ($event->getDataID()) { - $data = id(new PhabricatorTimelineEventData())->load( - $event->getDataID()); - } - - if ($data) { - $data = json_encode($data->getEventData()); - } else { - $data = 'null'; - } - - $form = new AphrontFormView(); - $form - ->setUser($user) - ->appendChild( - id(new AphrontFormStaticControl()) - ->setLabel('ID') - ->setValue($event->getID())) - ->appendChild( - id(new AphrontFormStaticControl()) - ->setLabel('Type') - ->setValue($event->getType())) - ->appendChild( - id(new AphrontFormTextAreaControl()) - ->setDisabled(true) - ->setLabel('Data') - ->setValue($data)) - ->appendChild( - id(new AphrontFormSubmitControl()) - ->addCancelButton('/daemon/timeline/')); - - $panel = new AphrontPanelView(); - $panel->setHeader('Event'); - $panel->setWidth(AphrontPanelView::WIDTH_FORM); - $panel->appendChild($form); - - $nav = $this->buildSideNavView(); - $nav->selectFilter('timeline'); - $nav->appendChild($panel); - - return $this->buildApplicationPage( - $nav, - array( - 'title' => 'Timeline Event', - )); - } - -}