From 2a1b8ce85bef36e45555a98b83d79c74080317fd Mon Sep 17 00:00:00 2001 From: epriestley Date: Wed, 13 Jul 2016 21:07:34 -0700 Subject: [PATCH] For now, hard limit task graph at 100 nodes Summary: Ref T4788. One install has some particularly impressive task graphs which are thousands of nodes large. The current graph is pretty broken in these cases. For now, just render a "too big to show" message. In the future, I'd plan to finesse this (e.g., show parents/children, show links to parents/children, etc). Test Plan: - Viewed a normal task. - Set limit to 3, viewed a task with graph size 6, saw an error message. - Viewed a revision stack graph (unaffected). Reviewers: chad Reviewed By: chad Maniphest Tasks: T4788 Differential Revision: https://secure.phabricator.com/D16295 --- .../ManiphestTaskDetailController.php | 15 +++++++++++- .../graph/PhabricatorObjectGraph.php | 24 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/applications/maniphest/controller/ManiphestTaskDetailController.php b/src/applications/maniphest/controller/ManiphestTaskDetailController.php index f544fa6b2c..34c7f54c11 100644 --- a/src/applications/maniphest/controller/ManiphestTaskDetailController.php +++ b/src/applications/maniphest/controller/ManiphestTaskDetailController.php @@ -87,12 +87,25 @@ final class ManiphestTaskDetailController extends ManiphestController { ->addPropertySection(pht('Description'), $description) ->addPropertySection(pht('Details'), $details); + $graph_limit = 100; $task_graph = id(new ManiphestTaskGraph()) ->setViewer($viewer) ->setSeedPHID($task->getPHID()) + ->setLimit($graph_limit) ->loadGraph(); if (!$task_graph->isEmpty()) { - $graph_table = $task_graph->newGraphTable(); + if ($task_graph->isOverLimit()) { + $message = pht( + 'Task graph too large to display (this task is connected to '. + 'more than %s other tasks).', + $graph_limit); + $message = phutil_tag('em', array(), $message); + $graph_table = id(new PHUIPropertyListView()) + ->addTextContent($message); + } else { + $graph_table = $task_graph->newGraphTable(); + } + $view->addPropertySection(pht('Task Graph'), $graph_table); } diff --git a/src/infrastructure/graph/PhabricatorObjectGraph.php b/src/infrastructure/graph/PhabricatorObjectGraph.php index 7a3790dea4..5e25cd8e33 100644 --- a/src/infrastructure/graph/PhabricatorObjectGraph.php +++ b/src/infrastructure/graph/PhabricatorObjectGraph.php @@ -9,6 +9,7 @@ abstract class PhabricatorObjectGraph private $seedPHID; private $objects; private $loadEntireGraph = false; + private $limit; public function setViewer(PhabricatorUser $viewer) { $this->viewer = $viewer; @@ -23,6 +24,15 @@ abstract class PhabricatorObjectGraph return $this->viewer; } + public function setLimit($limit) { + $this->limit = $limit; + return $this; + } + + public function getLimit() { + return $this->limit; + } + abstract protected function getEdgeTypes(); abstract protected function getParentEdgeType(); abstract protected function newQuery(); @@ -44,6 +54,16 @@ abstract class PhabricatorObjectGraph return (count($this->getNodes()) <= 2); } + final public function isOverLimit() { + $limit = $this->getLimit(); + + if (!$limit) { + return false; + } + + return (count($this->edgeReach) > $limit); + } + final public function getEdges($type) { $edges = idx($this->edges, $type, array()); @@ -72,6 +92,10 @@ abstract class PhabricatorObjectGraph } final protected function loadEdges(array $nodes) { + if ($this->isOverLimit()) { + return array_fill_keys($nodes, array()); + } + $edge_types = $this->getEdgeTypes(); $query = id(new PhabricatorEdgeQuery())