mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-23 22:10:55 +01:00
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
This commit is contained in:
parent
2ecdbbec10
commit
c39b64d963
5 changed files with 44 additions and 37 deletions
|
@ -89,10 +89,6 @@ abstract class AphrontTagView extends AphrontView {
|
|||
return $this->renderChildren();
|
||||
}
|
||||
|
||||
protected function willRender() {
|
||||
return;
|
||||
}
|
||||
|
||||
final public function render() {
|
||||
$this->willRender();
|
||||
|
||||
|
|
|
@ -149,6 +149,22 @@ abstract class AphrontView extends Phobject
|
|||
/* -( Rendering )---------------------------------------------------------- */
|
||||
|
||||
|
||||
/**
|
||||
* Inconsistent, unreliable pre-rendering hook.
|
||||
*
|
||||
* This hook //may// fire before views render. It is not fired reliably, and
|
||||
* may fire multiple times.
|
||||
*
|
||||
* If it does fire, views might use it to register data for later loads, but
|
||||
* almost no datasources support this now; this is currently only useful for
|
||||
* tokenizers. This mechanism might eventually see wider support or might be
|
||||
* removed.
|
||||
*/
|
||||
public function willRender() {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
abstract public function render();
|
||||
|
||||
|
||||
|
|
|
@ -94,6 +94,7 @@ final class AphrontFormView extends AphrontView {
|
|||
public function buildLayoutView() {
|
||||
foreach ($this->controls as $control) {
|
||||
$control->setUser($this->getUser());
|
||||
$control->willRender();
|
||||
}
|
||||
|
||||
return id(new PHUIFormLayoutView())
|
||||
|
|
|
@ -6,6 +6,7 @@ final class AphrontFormTokenizerControl extends AphrontFormControl {
|
|||
private $disableBehavior;
|
||||
private $limit;
|
||||
private $placeholder;
|
||||
private $handles;
|
||||
|
||||
public function setDatasource(PhabricatorTypeaheadDatasource $datasource) {
|
||||
$this->datasource = $datasource;
|
||||
|
@ -31,41 +32,17 @@ final class AphrontFormTokenizerControl extends AphrontFormControl {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function willRender() {
|
||||
// Load the handles now so we'll get a bulk load later on when we actually
|
||||
// render them.
|
||||
$this->loadHandles();
|
||||
}
|
||||
|
||||
protected function renderInput() {
|
||||
$name = $this->getName();
|
||||
$values = nonempty($this->getValue(), array());
|
||||
|
||||
// Values may either be handles (which are now legacy/deprecated) or
|
||||
// strings. Load handles for any PHIDs.
|
||||
$load = array();
|
||||
$handles = array();
|
||||
$select = array();
|
||||
foreach ($values as $value) {
|
||||
if ($value instanceof PhabricatorObjectHandle) {
|
||||
$handles[$value->getPHID()] = $value;
|
||||
$select[] = $value->getPHID();
|
||||
} else {
|
||||
$load[] = $value;
|
||||
$select[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Once this code path simplifies, move this prefetch to setValue()
|
||||
// so we can bulk load across multiple controls.
|
||||
|
||||
if ($load) {
|
||||
$viewer = $this->getUser();
|
||||
if (!$viewer) {
|
||||
// TODO: Clean this up when handles go away.
|
||||
throw new Exception(
|
||||
pht('Call setUser() before rendering tokenizer string values.'));
|
||||
}
|
||||
$loaded_handles = $viewer->loadHandles($load);
|
||||
$handles = $handles + iterator_to_array($loaded_handles);
|
||||
}
|
||||
|
||||
// Reorder the list into input order.
|
||||
$handles = array_select_keys($handles, $select);
|
||||
$handles = $this->loadHandles();
|
||||
$handles = iterator_to_array($handles);
|
||||
|
||||
if ($this->getID()) {
|
||||
$id = $this->getID();
|
||||
|
@ -112,4 +89,21 @@ final class AphrontFormTokenizerControl extends AphrontFormControl {
|
|||
return $template->render();
|
||||
}
|
||||
|
||||
private function loadHandles() {
|
||||
if ($this->handles === null) {
|
||||
$viewer = $this->getUser();
|
||||
if (!$viewer) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Call setUser() before rendering tokenizers. Use appendControl() '.
|
||||
'on AphrontFormView to do this easily.'));
|
||||
}
|
||||
|
||||
$values = nonempty($this->getValue(), array());
|
||||
$this->handles = $viewer->loadHandles($values);
|
||||
}
|
||||
|
||||
return $this->handles;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -152,7 +152,7 @@ final class PHUIListView extends AphrontTagView {
|
|||
return $this->items;
|
||||
}
|
||||
|
||||
protected function willRender() {
|
||||
public function willRender() {
|
||||
$key_map = array();
|
||||
foreach ($this->items as $item) {
|
||||
$key = $item->getKey();
|
||||
|
|
Loading…
Reference in a new issue