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

Modularize the Garbage Collector

Summary:
The GC is a big block of hard-coded application GCs right now. Among other things, this means third parties can't tap into the infrastructure.

Modularize it into `GarbageCollector` classes. This implements only one to prove the new stuff works; I'll followup with the rest in the next diff or few depending on how much mess I run into.

Test Plan: Used `bin/phd debug garbage` to run the collector in debug mode, observed reasonable output and behavior.

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

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

+78 -28
+5 -1
src/__phutil_library_map__.php
··· 816 816 'HeraldTransactionQuery' => 'applications/herald/query/HeraldTransactionQuery.php', 817 817 'HeraldTranscript' => 'applications/herald/storage/transcript/HeraldTranscript.php', 818 818 'HeraldTranscriptController' => 'applications/herald/controller/HeraldTranscriptController.php', 819 + 'HeraldTranscriptGarbageCollector' => 'applications/herald/garbagecollector/HeraldTranscriptGarbageCollector.php', 819 820 'HeraldTranscriptListController' => 'applications/herald/controller/HeraldTranscriptListController.php', 820 821 'HeraldTranscriptQuery' => 'applications/herald/query/HeraldTranscriptQuery.php', 821 822 'HeraldTranscriptTestCase' => 'applications/herald/storage/__tests__/HeraldTranscriptTestCase.php', ··· 1500 1501 'PhabricatorFlaggableInterface' => 'applications/flag/interface/PhabricatorFlaggableInterface.php', 1501 1502 'PhabricatorFlagsUIEventListener' => 'applications/flag/events/PhabricatorFlagsUIEventListener.php', 1502 1503 'PhabricatorFormExample' => 'applications/uiexample/examples/PhabricatorFormExample.php', 1504 + 'PhabricatorGarbageCollector' => 'infrastructure/daemon/garbagecollector/PhabricatorGarbageCollector.php', 1503 1505 'PhabricatorGarbageCollectorConfigOptions' => 'applications/config/option/PhabricatorGarbageCollectorConfigOptions.php', 1504 - 'PhabricatorGarbageCollectorDaemon' => 'infrastructure/daemon/PhabricatorGarbageCollectorDaemon.php', 1506 + 'PhabricatorGarbageCollectorDaemon' => 'infrastructure/daemon/garbagecollector/PhabricatorGarbageCollectorDaemon.php', 1505 1507 'PhabricatorGestureExample' => 'applications/uiexample/examples/PhabricatorGestureExample.php', 1506 1508 'PhabricatorGitGraphStream' => 'applications/repository/daemon/PhabricatorGitGraphStream.php', 1507 1509 'PhabricatorGlobalLock' => 'infrastructure/util/PhabricatorGlobalLock.php', ··· 3324 3326 1 => 'PhabricatorPolicyInterface', 3325 3327 ), 3326 3328 'HeraldTranscriptController' => 'HeraldController', 3329 + 'HeraldTranscriptGarbageCollector' => 'PhabricatorGarbageCollector', 3327 3330 'HeraldTranscriptListController' => 'HeraldController', 3328 3331 'HeraldTranscriptQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 3329 3332 'HeraldTranscriptTestCase' => 'PhabricatorTestCase', ··· 4112 4115 'PhabricatorFlaggableInterface' => 'PhabricatorPHIDInterface', 4113 4116 'PhabricatorFlagsUIEventListener' => 'PhabricatorEventListener', 4114 4117 'PhabricatorFormExample' => 'PhabricatorUIExample', 4118 + 'PhabricatorGarbageCollector' => 'Phobject', 4115 4119 'PhabricatorGarbageCollectorConfigOptions' => 'PhabricatorApplicationConfigOptions', 4116 4120 'PhabricatorGarbageCollectorDaemon' => 'PhabricatorDaemon', 4117 4121 'PhabricatorGestureExample' => 'PhabricatorUIExample',
+31
src/applications/herald/garbagecollector/HeraldTranscriptGarbageCollector.php
··· 1 + <?php 2 + 3 + final class HeraldTranscriptGarbageCollector 4 + extends PhabricatorGarbageCollector { 5 + 6 + public function collectGarbage() { 7 + $ttl = PhabricatorEnv::getEnvConfig('gcdaemon.ttl.herald-transcripts'); 8 + if ($ttl <= 0) { 9 + return false; 10 + } 11 + 12 + $table = new HeraldTranscript(); 13 + $conn_w = $table->establishConnection('w'); 14 + 15 + queryfx( 16 + $conn_w, 17 + 'UPDATE %T SET 18 + objectTranscript = "", 19 + ruleTranscripts = "", 20 + conditionTranscripts = "", 21 + applyTranscripts = "", 22 + garbageCollected = 1 23 + WHERE garbageCollected = 0 AND `time` < %d 24 + LIMIT 100', 25 + $table->getTableName(), 26 + time() - $ttl); 27 + 28 + return ($conn_w->getAffectedRows() == 100); 29 + } 30 + 31 + }
+30 -27
src/infrastructure/daemon/PhabricatorGarbageCollectorDaemon.php src/infrastructure/daemon/garbagecollector/PhabricatorGarbageCollectorDaemon.php
··· 9 9 final class PhabricatorGarbageCollectorDaemon extends PhabricatorDaemon { 10 10 11 11 public function run() { 12 + $collectors = id(new PhutilSymbolLoader()) 13 + ->setAncestorClass('PhabricatorGarbageCollector') 14 + ->loadObjects(); 15 + 12 16 do { 13 - $n_herald = $this->collectHeraldTranscripts(); 14 17 $n_daemon = $this->collectDaemonLogs(); 15 18 $n_parse = $this->collectParseCaches(); 16 19 $n_markup = $this->collectMarkupCaches(); ··· 22 25 $n_ccons = $this->collectExpiredConduitConnections(); 23 26 24 27 $collected = array( 25 - 'Herald Transcript' => $n_herald, 26 28 'Daemon Log' => $n_daemon, 27 29 'Differential Parse Cache' => $n_parse, 28 30 'Markup Cache' => $n_markup, ··· 41 43 } 42 44 43 45 $total = array_sum($collected); 46 + 47 + // TODO: This logic is unnecessarily complex for now to facilitate a 48 + // gradual conversion to the new GC infrastructure. 49 + 50 + $had_more_garbage = false; 51 + foreach ($collectors as $name => $collector) { 52 + $more_garbage = false; 53 + do { 54 + if ($more_garbage) { 55 + $this->log(pht('Collecting more garbage with "%s".', $name)); 56 + } else { 57 + $this->log(pht('Collecting garbage with "%s".', $name)); 58 + } 59 + 60 + $more_garbage = $collector->collectGarbage(); 61 + if ($more_garbage) { 62 + $had_more_garbage = true; 63 + } 64 + $this->stillWorking(); 65 + } while ($more_garbage); 66 + } 67 + 68 + if ($had_more_garbage) { 69 + $total += 100; 70 + } 71 + 44 72 if ($total < 100) { 45 73 // We didn't max out any of the GCs so we're basically caught up. Ease 46 74 // off the GC loop so we don't keep doing table scans just to delete ··· 51 79 } 52 80 } while (true); 53 81 54 - } 55 - 56 - private function collectHeraldTranscripts() { 57 - $ttl = PhabricatorEnv::getEnvConfig('gcdaemon.ttl.herald-transcripts'); 58 - if ($ttl <= 0) { 59 - return 0; 60 - } 61 - 62 - $table = new HeraldTranscript(); 63 - $conn_w = $table->establishConnection('w'); 64 - 65 - queryfx( 66 - $conn_w, 67 - 'UPDATE %T SET 68 - objectTranscript = "", 69 - ruleTranscripts = "", 70 - conditionTranscripts = "", 71 - applyTranscripts = "", 72 - garbageCollected = 1 73 - WHERE garbageCollected = 0 AND `time` < %d 74 - LIMIT 100', 75 - $table->getTableName(), 76 - time() - $ttl); 77 - 78 - return $conn_w->getAffectedRows(); 79 82 } 80 83 81 84 private function collectDaemonLogs() {
+12
src/infrastructure/daemon/garbagecollector/PhabricatorGarbageCollector.php
··· 1 + <?php 2 + 3 + abstract class PhabricatorGarbageCollector extends Phobject { 4 + 5 + /** 6 + * Collect garbage from whatever source this GC handles. 7 + * 8 + * @return bool True if there is more garbage to collect. 9 + */ 10 + abstract public function collectGarbage(); 11 + 12 + }