@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Improve handle loading semantics for tokenizers

Summary:
Ref T7689. Fixes T7688. When there are a bunch of tokenizers with different values of the same object type (e.g. 5 tokenizers with users a, b, c, d, e) we currently issue 5 separate queries to load their handles.

Improve this behavior in the common case so we can usually batch these loads.

Test Plan:
- In Maniphest, set the various search fields to different values.
- Used DarkConsole to examine query plan.
- Saw fewer queries after patch than before.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T7688, T7689

Differential Revision: https://secure.phabricator.com/D12261

+44 -37
-4
src/view/AphrontTagView.php
··· 89 89 return $this->renderChildren(); 90 90 } 91 91 92 - protected function willRender() { 93 - return; 94 - } 95 - 96 92 final public function render() { 97 93 $this->willRender(); 98 94
+16
src/view/AphrontView.php
··· 149 149 /* -( Rendering )---------------------------------------------------------- */ 150 150 151 151 152 + /** 153 + * Inconsistent, unreliable pre-rendering hook. 154 + * 155 + * This hook //may// fire before views render. It is not fired reliably, and 156 + * may fire multiple times. 157 + * 158 + * If it does fire, views might use it to register data for later loads, but 159 + * almost no datasources support this now; this is currently only useful for 160 + * tokenizers. This mechanism might eventually see wider support or might be 161 + * removed. 162 + */ 163 + public function willRender() { 164 + return; 165 + } 166 + 167 + 152 168 abstract public function render(); 153 169 154 170
+1
src/view/form/AphrontFormView.php
··· 94 94 public function buildLayoutView() { 95 95 foreach ($this->controls as $control) { 96 96 $control->setUser($this->getUser()); 97 + $control->willRender(); 97 98 } 98 99 99 100 return id(new PHUIFormLayoutView())
+26 -32
src/view/form/control/AphrontFormTokenizerControl.php
··· 6 6 private $disableBehavior; 7 7 private $limit; 8 8 private $placeholder; 9 + private $handles; 9 10 10 11 public function setDatasource(PhabricatorTypeaheadDatasource $datasource) { 11 12 $this->datasource = $datasource; ··· 31 32 return $this; 32 33 } 33 34 35 + public function willRender() { 36 + // Load the handles now so we'll get a bulk load later on when we actually 37 + // render them. 38 + $this->loadHandles(); 39 + } 40 + 34 41 protected function renderInput() { 35 42 $name = $this->getName(); 36 - $values = nonempty($this->getValue(), array()); 37 43 38 - // Values may either be handles (which are now legacy/deprecated) or 39 - // strings. Load handles for any PHIDs. 40 - $load = array(); 41 - $handles = array(); 42 - $select = array(); 43 - foreach ($values as $value) { 44 - if ($value instanceof PhabricatorObjectHandle) { 45 - $handles[$value->getPHID()] = $value; 46 - $select[] = $value->getPHID(); 47 - } else { 48 - $load[] = $value; 49 - $select[] = $value; 50 - } 51 - } 52 - 53 - // TODO: Once this code path simplifies, move this prefetch to setValue() 54 - // so we can bulk load across multiple controls. 55 - 56 - if ($load) { 57 - $viewer = $this->getUser(); 58 - if (!$viewer) { 59 - // TODO: Clean this up when handles go away. 60 - throw new Exception( 61 - pht('Call setUser() before rendering tokenizer string values.')); 62 - } 63 - $loaded_handles = $viewer->loadHandles($load); 64 - $handles = $handles + iterator_to_array($loaded_handles); 65 - } 66 - 67 - // Reorder the list into input order. 68 - $handles = array_select_keys($handles, $select); 44 + $handles = $this->loadHandles(); 45 + $handles = iterator_to_array($handles); 69 46 70 47 if ($this->getID()) { 71 48 $id = $this->getID(); ··· 110 87 } 111 88 112 89 return $template->render(); 90 + } 91 + 92 + private function loadHandles() { 93 + if ($this->handles === null) { 94 + $viewer = $this->getUser(); 95 + if (!$viewer) { 96 + throw new Exception( 97 + pht( 98 + 'Call setUser() before rendering tokenizers. Use appendControl() '. 99 + 'on AphrontFormView to do this easily.')); 100 + } 101 + 102 + $values = nonempty($this->getValue(), array()); 103 + $this->handles = $viewer->loadHandles($values); 104 + } 105 + 106 + return $this->handles; 113 107 } 114 108 115 109 }
+1 -1
src/view/phui/PHUIListView.php
··· 152 152 return $this->items; 153 153 } 154 154 155 - protected function willRender() { 155 + public function willRender() { 156 156 $key_map = array(); 157 157 foreach ($this->items as $item) { 158 158 $key = $item->getKey();