@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.

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

+53 -14
+53 -14
src/applications/conpherence/query/ConpherenceThreadQuery.php
··· 151 151 } 152 152 } 153 153 154 - protected function buildJoinClause(AphrontDatabaseConnection $conn_r) { 155 - $joins = array(); 154 + protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) { 155 + $joins = parent::buildJoinClauseParts($conn); 156 156 157 157 if ($this->participantPHIDs !== null) { 158 158 $joins[] = qsprintf( 159 - $conn_r, 159 + $conn, 160 160 'JOIN %T p ON p.conpherencePHID = thread.phid', 161 161 id(new ConpherenceParticipant())->getTableName()); 162 162 } 163 163 164 164 if (strlen($this->fulltext)) { 165 165 $joins[] = qsprintf( 166 - $conn_r, 166 + $conn, 167 167 'JOIN %T idx ON idx.threadPHID = thread.phid', 168 168 id(new ConpherenceIndex())->getTableName()); 169 169 } 170 170 171 - $joins[] = $this->buildApplicationSearchJoinClause($conn_r); 172 - return implode(' ', $joins); 171 + // See note in buildWhereClauseParts() about this optimization. 172 + $viewer = $this->getViewer(); 173 + if (!$viewer->isOmnipotent() && $viewer->isLoggedIn()) { 174 + $joins[] = qsprintf( 175 + $conn, 176 + 'LEFT JOIN %T vp ON vp.conpherencePHID = thread.phid 177 + AND vp.participantPHID = %s', 178 + id(new ConpherenceParticipant())->getTableName(), 179 + $viewer->getPHID()); 180 + } 181 + 182 + return $joins; 173 183 } 174 184 175 - protected function buildWhereClause(AphrontDatabaseConnection $conn_r) { 176 - $where = array(); 185 + protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { 186 + $where = parent::buildWhereClauseParts($conn); 187 + 188 + // Optimize policy filtering of private rooms. If we are not looking for 189 + // particular rooms by ID or PHID, we can just skip over any rooms with 190 + // "View Policy: Room Participants" if the viewer isn't a participant: we 191 + // know they won't be able to see the room. 192 + // This avoids overheating browse/search queries, since it's common for 193 + // a large number of rooms to be private and have this view policy. 194 + $viewer = $this->getViewer(); 195 + 196 + $can_optimize = 197 + !$viewer->isOmnipotent() && 198 + ($this->ids === null) && 199 + ($this->phids === null); 200 + 201 + if ($can_optimize) { 202 + $members_policy = id(new ConpherenceThreadMembersPolicyRule()) 203 + ->getObjectPolicyFullKey(); 177 204 178 - $where[] = $this->buildPagingClause($conn_r); 205 + if ($viewer->isLoggedIn()) { 206 + $where[] = qsprintf( 207 + $conn, 208 + 'thread.viewPolicy != %s OR vp.participantPHID = %s', 209 + $members_policy, 210 + $viewer->getPHID()); 211 + } else { 212 + $where[] = qsprintf( 213 + $conn, 214 + 'thread.viewPolicy != %s', 215 + $members_policy); 216 + } 217 + } 179 218 180 219 if ($this->ids !== null) { 181 220 $where[] = qsprintf( 182 - $conn_r, 221 + $conn, 183 222 'thread.id IN (%Ld)', 184 223 $this->ids); 185 224 } 186 225 187 226 if ($this->phids !== null) { 188 227 $where[] = qsprintf( 189 - $conn_r, 228 + $conn, 190 229 'thread.phid IN (%Ls)', 191 230 $this->phids); 192 231 } 193 232 194 233 if ($this->participantPHIDs !== null) { 195 234 $where[] = qsprintf( 196 - $conn_r, 235 + $conn, 197 236 'p.participantPHID IN (%Ls)', 198 237 $this->participantPHIDs); 199 238 } 200 239 201 240 if (strlen($this->fulltext)) { 202 241 $where[] = qsprintf( 203 - $conn_r, 242 + $conn, 204 243 'MATCH(idx.corpus) AGAINST (%s IN BOOLEAN MODE)', 205 244 $this->fulltext); 206 245 } 207 246 208 - return $this->formatWhereClause($where); 247 + return $where; 209 248 } 210 249 211 250 private function loadParticipantsAndInitHandles(array $conpherences) {