mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-18 12:52:42 +01:00
Optimize filtering private threads when querying Conpherence
Summary: Because most threads are private, this query can overheat the policy filter (today, probably only on this install). Improve the common case by skipping "Visible To: Room Participants" threads if the viewer isn't a participant. This means they don't hit the application and don't count toward overheating the filter. Test Plan: Viewed Conpherence threads. Reviewers: chad Reviewed By: chad Differential Revision: https://secure.phabricator.com/D16740
This commit is contained in:
parent
7678f412be
commit
4058726b3a
1 changed files with 53 additions and 14 deletions
|
@ -151,61 +151,100 @@ final class ConpherenceThreadQuery
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildJoinClause(AphrontDatabaseConnection $conn_r) {
|
protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) {
|
||||||
$joins = array();
|
$joins = parent::buildJoinClauseParts($conn);
|
||||||
|
|
||||||
if ($this->participantPHIDs !== null) {
|
if ($this->participantPHIDs !== null) {
|
||||||
$joins[] = qsprintf(
|
$joins[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'JOIN %T p ON p.conpherencePHID = thread.phid',
|
'JOIN %T p ON p.conpherencePHID = thread.phid',
|
||||||
id(new ConpherenceParticipant())->getTableName());
|
id(new ConpherenceParticipant())->getTableName());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen($this->fulltext)) {
|
if (strlen($this->fulltext)) {
|
||||||
$joins[] = qsprintf(
|
$joins[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'JOIN %T idx ON idx.threadPHID = thread.phid',
|
'JOIN %T idx ON idx.threadPHID = thread.phid',
|
||||||
id(new ConpherenceIndex())->getTableName());
|
id(new ConpherenceIndex())->getTableName());
|
||||||
}
|
}
|
||||||
|
|
||||||
$joins[] = $this->buildApplicationSearchJoinClause($conn_r);
|
// See note in buildWhereClauseParts() about this optimization.
|
||||||
return implode(' ', $joins);
|
$viewer = $this->getViewer();
|
||||||
|
if (!$viewer->isOmnipotent() && $viewer->isLoggedIn()) {
|
||||||
|
$joins[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'LEFT JOIN %T vp ON vp.conpherencePHID = thread.phid
|
||||||
|
AND vp.participantPHID = %s',
|
||||||
|
id(new ConpherenceParticipant())->getTableName(),
|
||||||
|
$viewer->getPHID());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $joins;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
|
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
|
||||||
$where = array();
|
$where = parent::buildWhereClauseParts($conn);
|
||||||
|
|
||||||
$where[] = $this->buildPagingClause($conn_r);
|
// Optimize policy filtering of private rooms. If we are not looking for
|
||||||
|
// particular rooms by ID or PHID, we can just skip over any rooms with
|
||||||
|
// "View Policy: Room Participants" if the viewer isn't a participant: we
|
||||||
|
// know they won't be able to see the room.
|
||||||
|
// This avoids overheating browse/search queries, since it's common for
|
||||||
|
// a large number of rooms to be private and have this view policy.
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
$can_optimize =
|
||||||
|
!$viewer->isOmnipotent() &&
|
||||||
|
($this->ids === null) &&
|
||||||
|
($this->phids === null);
|
||||||
|
|
||||||
|
if ($can_optimize) {
|
||||||
|
$members_policy = id(new ConpherenceThreadMembersPolicyRule())
|
||||||
|
->getObjectPolicyFullKey();
|
||||||
|
|
||||||
|
if ($viewer->isLoggedIn()) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'thread.viewPolicy != %s OR vp.participantPHID = %s',
|
||||||
|
$members_policy,
|
||||||
|
$viewer->getPHID());
|
||||||
|
} else {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'thread.viewPolicy != %s',
|
||||||
|
$members_policy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->ids !== null) {
|
if ($this->ids !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'thread.id IN (%Ld)',
|
'thread.id IN (%Ld)',
|
||||||
$this->ids);
|
$this->ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->phids !== null) {
|
if ($this->phids !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'thread.phid IN (%Ls)',
|
'thread.phid IN (%Ls)',
|
||||||
$this->phids);
|
$this->phids);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->participantPHIDs !== null) {
|
if ($this->participantPHIDs !== null) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'p.participantPHID IN (%Ls)',
|
'p.participantPHID IN (%Ls)',
|
||||||
$this->participantPHIDs);
|
$this->participantPHIDs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen($this->fulltext)) {
|
if (strlen($this->fulltext)) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn,
|
||||||
'MATCH(idx.corpus) AGAINST (%s IN BOOLEAN MODE)',
|
'MATCH(idx.corpus) AGAINST (%s IN BOOLEAN MODE)',
|
||||||
$this->fulltext);
|
$this->fulltext);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->formatWhereClause($where);
|
return $where;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function loadParticipantsAndInitHandles(array $conpherences) {
|
private function loadParticipantsAndInitHandles(array $conpherences) {
|
||||||
|
|
Loading…
Reference in a new issue