1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-10 00:42:41 +01:00

Fully modularize DestructionEngine

Summary: Ref T9979. Convert all DestructionEngine behaviors to extensions.

Test Plan:
{F1033244}

Destroyed an object, verifying:

  - Herald transcripts were destroyed;
  - edges were destroyed;
  - flags were destroyed;
  - tokens were destroyed;
  - transactions were destroyed;
  - worker tasks were cancelled.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T9979

Differential Revision: https://secure.phabricator.com/D14832
This commit is contained in:
epriestley 2015-12-20 08:11:59 -08:00
parent 674388ce6a
commit 4bba3fd4c1
13 changed files with 246 additions and 118 deletions

View file

@ -1196,6 +1196,7 @@ phutil_register_library_map(array(
'HeraldTransactionQuery' => 'applications/herald/query/HeraldTransactionQuery.php',
'HeraldTranscript' => 'applications/herald/storage/transcript/HeraldTranscript.php',
'HeraldTranscriptController' => 'applications/herald/controller/HeraldTranscriptController.php',
'HeraldTranscriptDestructionEngineExtension' => 'applications/herald/engineextension/HeraldTranscriptDestructionEngineExtension.php',
'HeraldTranscriptGarbageCollector' => 'applications/herald/garbagecollector/HeraldTranscriptGarbageCollector.php',
'HeraldTranscriptListController' => 'applications/herald/controller/HeraldTranscriptListController.php',
'HeraldTranscriptQuery' => 'applications/herald/query/HeraldTranscriptQuery.php',
@ -1876,7 +1877,7 @@ phutil_register_library_map(array(
'PhabricatorChatLogQuery' => 'applications/chatlog/query/PhabricatorChatLogQuery.php',
'PhabricatorChunkedFileStorageEngine' => 'applications/files/engine/PhabricatorChunkedFileStorageEngine.php',
'PhabricatorClusterConfigOptions' => 'applications/config/option/PhabricatorClusterConfigOptions.php',
'PhabricatorCommentEditEngineExtension' => 'applications/transactions/editengineextension/PhabricatorCommentEditEngineExtension.php',
'PhabricatorCommentEditEngineExtension' => 'applications/transactions/engineextension/PhabricatorCommentEditEngineExtension.php',
'PhabricatorCommentEditField' => 'applications/transactions/editfield/PhabricatorCommentEditField.php',
'PhabricatorCommentEditType' => 'applications/transactions/edittype/PhabricatorCommentEditType.php',
'PhabricatorCommitBranchesField' => 'applications/repository/customfield/PhabricatorCommitBranchesField.php',
@ -2157,6 +2158,7 @@ phutil_register_library_map(array(
'PhabricatorEdgeTestCase' => 'infrastructure/edges/__tests__/PhabricatorEdgeTestCase.php',
'PhabricatorEdgeType' => 'infrastructure/edges/type/PhabricatorEdgeType.php',
'PhabricatorEdgeTypeTestCase' => 'infrastructure/edges/type/__tests__/PhabricatorEdgeTypeTestCase.php',
'PhabricatorEdgesDestructionEngineExtension' => 'infrastructure/edges/engineextension/PhabricatorEdgesDestructionEngineExtension.php',
'PhabricatorEditEngine' => 'applications/transactions/editengine/PhabricatorEditEngine.php',
'PhabricatorEditEngineAPIMethod' => 'applications/transactions/editengine/PhabricatorEditEngineAPIMethod.php',
'PhabricatorEditEngineCommentAction' => 'applications/transactions/commentaction/PhabricatorEditEngineCommentAction.php',
@ -2180,8 +2182,8 @@ phutil_register_library_map(array(
'PhabricatorEditEngineConfigurationTransactionQuery' => 'applications/transactions/query/PhabricatorEditEngineConfigurationTransactionQuery.php',
'PhabricatorEditEngineConfigurationViewController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationViewController.php',
'PhabricatorEditEngineController' => 'applications/transactions/controller/PhabricatorEditEngineController.php',
'PhabricatorEditEngineExtension' => 'applications/transactions/editengineextension/PhabricatorEditEngineExtension.php',
'PhabricatorEditEngineExtensionModule' => 'applications/transactions/editengineextension/PhabricatorEditEngineExtensionModule.php',
'PhabricatorEditEngineExtension' => 'applications/transactions/engineextension/PhabricatorEditEngineExtension.php',
'PhabricatorEditEngineExtensionModule' => 'applications/transactions/engineextension/PhabricatorEditEngineExtensionModule.php',
'PhabricatorEditEngineListController' => 'applications/transactions/controller/PhabricatorEditEngineListController.php',
'PhabricatorEditEngineQuery' => 'applications/transactions/query/PhabricatorEditEngineQuery.php',
'PhabricatorEditEngineSearchEngine' => 'applications/transactions/query/PhabricatorEditEngineSearchEngine.php',
@ -2315,6 +2317,7 @@ phutil_register_library_map(array(
'PhabricatorFlagController' => 'applications/flag/controller/PhabricatorFlagController.php',
'PhabricatorFlagDAO' => 'applications/flag/storage/PhabricatorFlagDAO.php',
'PhabricatorFlagDeleteController' => 'applications/flag/controller/PhabricatorFlagDeleteController.php',
'PhabricatorFlagDestructionEngineExtension' => 'applications/flag/engineextension/PhabricatorFlagDestructionEngineExtension.php',
'PhabricatorFlagEditController' => 'applications/flag/controller/PhabricatorFlagEditController.php',
'PhabricatorFlagListController' => 'applications/flag/controller/PhabricatorFlagListController.php',
'PhabricatorFlagQuery' => 'applications/flag/query/PhabricatorFlagQuery.php',
@ -2538,6 +2541,7 @@ phutil_register_library_map(array(
'PhabricatorNotificationClient' => 'applications/notification/client/PhabricatorNotificationClient.php',
'PhabricatorNotificationConfigOptions' => 'applications/config/option/PhabricatorNotificationConfigOptions.php',
'PhabricatorNotificationController' => 'applications/notification/controller/PhabricatorNotificationController.php',
'PhabricatorNotificationDestructionEngineExtension' => 'applications/notification/engineextension/PhabricatorNotificationDestructionEngineExtension.php',
'PhabricatorNotificationIndividualController' => 'applications/notification/controller/PhabricatorNotificationIndividualController.php',
'PhabricatorNotificationListController' => 'applications/notification/controller/PhabricatorNotificationListController.php',
'PhabricatorNotificationPanelController' => 'applications/notification/controller/PhabricatorNotificationPanelController.php',
@ -3213,6 +3217,7 @@ phutil_register_library_map(array(
'PhabricatorTokenCount' => 'applications/tokens/storage/PhabricatorTokenCount.php',
'PhabricatorTokenCountQuery' => 'applications/tokens/query/PhabricatorTokenCountQuery.php',
'PhabricatorTokenDAO' => 'applications/tokens/storage/PhabricatorTokenDAO.php',
'PhabricatorTokenDestructionEngineExtension' => 'applications/tokens/engineextension/PhabricatorTokenDestructionEngineExtension.php',
'PhabricatorTokenGiveController' => 'applications/tokens/controller/PhabricatorTokenGiveController.php',
'PhabricatorTokenGiven' => 'applications/tokens/storage/PhabricatorTokenGiven.php',
'PhabricatorTokenGivenController' => 'applications/tokens/controller/PhabricatorTokenGivenController.php',
@ -3231,6 +3236,7 @@ phutil_register_library_map(array(
'PhabricatorTooltipUIExample' => 'applications/uiexample/examples/PhabricatorTooltipUIExample.php',
'PhabricatorTransactions' => 'applications/transactions/constants/PhabricatorTransactions.php',
'PhabricatorTransactionsApplication' => 'applications/transactions/application/PhabricatorTransactionsApplication.php',
'PhabricatorTransactionsDestructionEngineExtension' => 'applications/transactions/engineextension/PhabricatorTransactionsDestructionEngineExtension.php',
'PhabricatorTransformedFile' => 'applications/files/storage/PhabricatorTransformedFile.php',
'PhabricatorTranslationsConfigOptions' => 'applications/config/option/PhabricatorTranslationsConfigOptions.php',
'PhabricatorTriggerAction' => 'infrastructure/daemon/workers/action/PhabricatorTriggerAction.php',
@ -3313,6 +3319,7 @@ phutil_register_library_map(array(
'PhabricatorWorkerBulkJobWorker' => 'infrastructure/daemon/workers/bulk/PhabricatorWorkerBulkJobWorker.php',
'PhabricatorWorkerBulkTask' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerBulkTask.php',
'PhabricatorWorkerDAO' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerDAO.php',
'PhabricatorWorkerDestructionEngineExtension' => 'infrastructure/daemon/workers/engineextension/PhabricatorWorkerDestructionEngineExtension.php',
'PhabricatorWorkerLeaseQuery' => 'infrastructure/daemon/workers/query/PhabricatorWorkerLeaseQuery.php',
'PhabricatorWorkerManagementCancelWorkflow' => 'infrastructure/daemon/workers/management/PhabricatorWorkerManagementCancelWorkflow.php',
'PhabricatorWorkerManagementExecuteWorkflow' => 'infrastructure/daemon/workers/management/PhabricatorWorkerManagementExecuteWorkflow.php',
@ -5213,6 +5220,7 @@ phutil_register_library_map(array(
'PhabricatorDestructibleInterface',
),
'HeraldTranscriptController' => 'HeraldController',
'HeraldTranscriptDestructionEngineExtension' => 'PhabricatorDestructionEngineExtension',
'HeraldTranscriptGarbageCollector' => 'PhabricatorGarbageCollector',
'HeraldTranscriptListController' => 'HeraldController',
'HeraldTranscriptQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
@ -6329,6 +6337,7 @@ phutil_register_library_map(array(
'PhabricatorEdgeTestCase' => 'PhabricatorTestCase',
'PhabricatorEdgeType' => 'Phobject',
'PhabricatorEdgeTypeTestCase' => 'PhabricatorTestCase',
'PhabricatorEdgesDestructionEngineExtension' => 'PhabricatorDestructionEngineExtension',
'PhabricatorEditEngine' => array(
'Phobject',
'PhabricatorPolicyInterface',
@ -6525,6 +6534,7 @@ phutil_register_library_map(array(
'PhabricatorFlagController' => 'PhabricatorController',
'PhabricatorFlagDAO' => 'PhabricatorLiskDAO',
'PhabricatorFlagDeleteController' => 'PhabricatorFlagController',
'PhabricatorFlagDestructionEngineExtension' => 'PhabricatorDestructionEngineExtension',
'PhabricatorFlagEditController' => 'PhabricatorFlagController',
'PhabricatorFlagListController' => 'PhabricatorFlagController',
'PhabricatorFlagQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
@ -6766,6 +6776,7 @@ phutil_register_library_map(array(
'PhabricatorNotificationClient' => 'Phobject',
'PhabricatorNotificationConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorNotificationController' => 'PhabricatorController',
'PhabricatorNotificationDestructionEngineExtension' => 'PhabricatorDestructionEngineExtension',
'PhabricatorNotificationIndividualController' => 'PhabricatorNotificationController',
'PhabricatorNotificationListController' => 'PhabricatorNotificationController',
'PhabricatorNotificationPanelController' => 'PhabricatorNotificationController',
@ -7571,6 +7582,7 @@ phutil_register_library_map(array(
'PhabricatorTokenCount' => 'PhabricatorTokenDAO',
'PhabricatorTokenCountQuery' => 'PhabricatorOffsetPagedQuery',
'PhabricatorTokenDAO' => 'PhabricatorLiskDAO',
'PhabricatorTokenDestructionEngineExtension' => 'PhabricatorDestructionEngineExtension',
'PhabricatorTokenGiveController' => 'PhabricatorTokenController',
'PhabricatorTokenGiven' => array(
'PhabricatorTokenDAO',
@ -7591,6 +7603,7 @@ phutil_register_library_map(array(
'PhabricatorTooltipUIExample' => 'PhabricatorUIExample',
'PhabricatorTransactions' => 'Phobject',
'PhabricatorTransactionsApplication' => 'PhabricatorApplication',
'PhabricatorTransactionsDestructionEngineExtension' => 'PhabricatorDestructionEngineExtension',
'PhabricatorTransformedFile' => 'PhabricatorFileDAO',
'PhabricatorTranslationsConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorTriggerAction' => 'Phobject',
@ -7694,6 +7707,7 @@ phutil_register_library_map(array(
'PhabricatorWorkerBulkJobWorker' => 'PhabricatorWorker',
'PhabricatorWorkerBulkTask' => 'PhabricatorWorkerDAO',
'PhabricatorWorkerDAO' => 'PhabricatorLiskDAO',
'PhabricatorWorkerDestructionEngineExtension' => 'PhabricatorDestructionEngineExtension',
'PhabricatorWorkerLeaseQuery' => 'PhabricatorQuery',
'PhabricatorWorkerManagementCancelWorkflow' => 'PhabricatorWorkerManagementWorkflow',
'PhabricatorWorkerManagementExecuteWorkflow' => 'PhabricatorWorkerManagementWorkflow',

View file

@ -0,0 +1,35 @@
<?php
final class PhabricatorFlagDestructionEngineExtension
extends PhabricatorDestructionEngineExtension {
const EXTENSIONKEY = 'flags';
public function getExtensionName() {
return pht('Flags');
}
public function destroyObject(
PhabricatorDestructionEngine $engine,
$object) {
$object_phid = $object->getPHID();
if ($object instanceof PhabricatorFlaggableInterface) {
$flags = id(new PhabricatorFlag())->loadAllWhere(
'objectPHID = %s',
$object_phid);
foreach ($flags as $flag) {
$flag->delete();
}
}
$flags = id(new PhabricatorFlag())->loadAllWhere(
'ownerPHID = %s',
$object_phid);
foreach ($flags as $flag) {
$flag->delete();
}
}
}

View file

@ -0,0 +1,26 @@
<?php
final class HeraldTranscriptDestructionEngineExtension
extends PhabricatorDestructionEngineExtension {
const EXTENSIONKEY = 'herald.transcripts';
public function getExtensionName() {
return pht('Herald Transcripts');
}
public function destroyObject(
PhabricatorDestructionEngine $engine,
$object) {
$object_phid = $object->getPHID();
$transcripts = id(new HeraldTranscript())->loadAllWhere(
'objectPHID = %s',
$object_phid);
foreach ($transcripts as $transcript) {
$engine->destroyObject($transcript);
}
}
}

View file

@ -0,0 +1,26 @@
<?php
final class PhabricatorNotificationDestructionEngineExtension
extends PhabricatorDestructionEngineExtension {
const EXTENSIONKEY = 'notifications';
public function getExtensionName() {
return pht('Notifications');
}
public function destroyObject(
PhabricatorDestructionEngine $engine,
$object) {
$table = new PhabricatorFeedStoryNotification();
$conn_w = $table->establishConnection('w');
queryfx(
$conn_w,
'DELETE FROM %T WHERE primaryObjectPHID = %s',
$table->getTableName(),
$object->getPHID());
}
}

View file

@ -38,126 +38,22 @@ final class PhabricatorDestructionEngine extends Phobject {
$object->destroyObjectPermanently($this);
$extensions = PhabricatorDestructionEngineExtension::getAllExtensions();
foreach ($extensions as $key => $extension) {
if (!$extension->canDestroyObject($this, $object)) {
unset($extensions[$key]);
continue;
}
}
foreach ($extensions as $key => $extension) {
$extension->destroyObject($this, $object);
}
if ($object_phid) {
$this->destroyEdges($object_phid);
if ($object instanceof PhabricatorApplicationTransactionInterface) {
$template = $object->getApplicationTransactionTemplate();
$this->destroyTransactions($template, $object_phid);
}
$this->destroyWorkerTasks($object_phid);
$this->destroyNotifications($object_phid);
}
// Nuke any Herald transcripts of the object, because they may contain
// field data.
// TODO: Define an interface so we don't have to do this for transactions
// and other objects with no Herald adapters?
$transcripts = id(new HeraldTranscript())->loadAllWhere(
'objectPHID = %s',
$object_phid);
foreach ($transcripts as $transcript) {
$transcript->destroyObjectPermanently($this);
}
// TODO: Remove stuff from search indexes?
if ($object instanceof PhabricatorFlaggableInterface) {
$flags = id(new PhabricatorFlag())->loadAllWhere(
'objectPHID = %s', $object_phid);
foreach ($flags as $flag) {
$flag->delete();
}
}
$flags = id(new PhabricatorFlag())->loadAllWhere(
'ownerPHID = %s', $object_phid);
foreach ($flags as $flag) {
$flag->delete();
}
if ($object instanceof PhabricatorTokenReceiverInterface) {
$tokens = id(new PhabricatorTokenGiven())->loadAllWhere(
'objectPHID = %s', $object_phid);
foreach ($tokens as $token) {
$token->delete();
}
}
}
private function destroyEdges($src_phid) {
try {
$edges = id(new PhabricatorEdgeQuery())
->withSourcePHIDs(array($src_phid))
->execute();
} catch (Exception $ex) {
// This is (presumably) a "no edges for this PHID type" exception.
return;
}
$editor = new PhabricatorEdgeEditor();
foreach ($edges as $type => $type_edges) {
foreach ($type_edges as $src => $src_edges) {
foreach ($src_edges as $dst => $edge) {
$editor->removeEdge($edge['src'], $edge['type'], $edge['dst']);
$extensions = PhabricatorDestructionEngineExtension::getAllExtensions();
foreach ($extensions as $key => $extension) {
if (!$extension->canDestroyObject($this, $object)) {
unset($extensions[$key]);
continue;
}
}
}
$editor->save();
}
private function destroyTransactions(
PhabricatorApplicationTransaction $template,
$object_phid) {
$xactions = $template->loadAllWhere('objectPHID = %s', $object_phid);
foreach ($xactions as $xaction) {
$this->destroyObject($xaction);
foreach ($extensions as $key => $extension) {
$extension->destroyObject($this, $object);
}
}
}
private function destroyWorkerTasks($object_phid) {
$tasks = id(new PhabricatorWorkerActiveTask())->loadAllWhere(
'objectPHID = %s',
$object_phid);
foreach ($tasks as $task) {
$task->archiveTask(
PhabricatorWorkerArchiveTask::RESULT_CANCELLED,
0);
}
}
private function destroyNotifications($object_phid) {
$table = new PhabricatorFeedStoryNotification();
$conn_w = $table->establishConnection('w');
queryfx(
$conn_w,
'DELETE FROM %T WHERE primaryObjectPHID = %s',
$table->getTableName(),
$object_phid);
}
private function destroyAlmanacProperties($object_phid) {}
public function getObjectPHID($object) {
private function getObjectPHID($object) {
if (!is_object($object)) {
return null;
}

View file

@ -7,9 +7,13 @@ abstract class PhabricatorDestructionEngineExtension extends Phobject {
}
abstract public function getExtensionName();
abstract public function canDestroyObject(
public function canDestroyObject(
PhabricatorDestructionEngine $engine,
$object);
$object) {
return true;
}
abstract public function destroyObject(
PhabricatorDestructionEngine $engine,
$object);

View file

@ -0,0 +1,31 @@
<?php
final class PhabricatorTokenDestructionEngineExtension
extends PhabricatorDestructionEngineExtension {
const EXTENSIONKEY = 'tokens';
public function getExtensionName() {
return pht('Tokens');
}
public function canDestroyObject(
PhabricatorDestructionEngine $engine,
$object) {
return ($object instanceof PhabricatorTokenReceiverInterface);
}
public function destroyObject(
PhabricatorDestructionEngine $engine,
$object) {
$tokens = id(new PhabricatorTokenGiven())->loadAllWhere(
'objectPHID = %s',
$object->getPHID());
foreach ($tokens as $token) {
$token->delete();
}
}
}

View file

@ -0,0 +1,31 @@
<?php
final class PhabricatorTransactionsDestructionEngineExtension
extends PhabricatorDestructionEngineExtension {
const EXTENSIONKEY = 'transactions';
public function getExtensionName() {
return pht('Transactions');
}
public function canDestroyObject(
PhabricatorDestructionEngine $engine,
$object) {
return ($object instanceof PhabricatorApplicationTransactionInterface);
}
public function destroyObject(
PhabricatorDestructionEngine $engine,
$object) {
$template = $object->getApplicationTransactionTemplate();
$xactions = $template->loadAllWhere(
'objectPHID = %s',
$object->getPHID());
foreach ($xactions as $xaction) {
$engine->destroyObject($xaction);
}
}
}

View file

@ -0,0 +1,27 @@
<?php
final class PhabricatorWorkerDestructionEngineExtension
extends PhabricatorDestructionEngineExtension {
const EXTENSIONKEY = 'workers';
public function getExtensionName() {
return pht('Worker Tasks');
}
public function destroyObject(
PhabricatorDestructionEngine $engine,
$object) {
$tasks = id(new PhabricatorWorkerActiveTask())->loadAllWhere(
'objectPHID = %s',
$object->getPHID());
foreach ($tasks as $task) {
$task->archiveTask(
PhabricatorWorkerArchiveTask::RESULT_CANCELLED,
0);
}
}
}

View file

@ -0,0 +1,38 @@
<?php
final class PhabricatorEdgesDestructionEngineExtension
extends PhabricatorDestructionEngineExtension {
const EXTENSIONKEY = 'edges';
public function getExtensionName() {
return pht('Edges');
}
public function destroyObject(
PhabricatorDestructionEngine $engine,
$object) {
$src_phid = $object->getPHID();
try {
$edges = id(new PhabricatorEdgeQuery())
->withSourcePHIDs(array($src_phid))
->execute();
} catch (Exception $ex) {
// This is (presumably) a "no edges for this PHID type" exception.
return;
}
$editor = new PhabricatorEdgeEditor();
foreach ($edges as $type => $type_edges) {
foreach ($type_edges as $src => $src_edges) {
foreach ($src_edges as $dst => $edge) {
$editor->removeEdge($edge['src'], $edge['type'], $edge['dst']);
}
}
}
$editor->save();
}
}