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

Make daemons perform file deletion

Summary:
Deletion is a possibly time-intensive process, especially with large
files that are backed by high-latency, chunked storage (such as
S3). Even ~200mb objects take minutes to delete, which makes for an
unhappy experience. Fixes T10828.

Test Plan:
Delete a large file, and stare in awe of the swiftness with
which I am redirected to the main file application.

Reviewers: #blessed_reviewers, epriestley

Reviewed By: #blessed_reviewers, epriestley

Subscribers: thoughtpolice, Korvin

Maniphest Tasks: T10828

Differential Revision: https://secure.phabricator.com/D15743
This commit is contained in:
Austin McKinley 2017-04-18 11:07:24 -07:00
parent e187519f00
commit be00264ae7
10 changed files with 69 additions and 4 deletions

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_file.file
ADD isDeleted BOOL NOT NULL DEFAULT 0;

View file

@ -1098,6 +1098,7 @@ phutil_register_library_map(array(
'FileAllocateConduitAPIMethod' => 'applications/files/conduit/FileAllocateConduitAPIMethod.php',
'FileConduitAPIMethod' => 'applications/files/conduit/FileConduitAPIMethod.php',
'FileCreateMailReceiver' => 'applications/files/mail/FileCreateMailReceiver.php',
'FileDeletionWorker' => 'applications/files/worker/FileDeletionWorker.php',
'FileDownloadConduitAPIMethod' => 'applications/files/conduit/FileDownloadConduitAPIMethod.php',
'FileInfoConduitAPIMethod' => 'applications/files/conduit/FileInfoConduitAPIMethod.php',
'FileMailReceiver' => 'applications/files/mail/FileMailReceiver.php',
@ -5977,6 +5978,7 @@ phutil_register_library_map(array(
'FileAllocateConduitAPIMethod' => 'FileConduitAPIMethod',
'FileConduitAPIMethod' => 'ConduitAPIMethod',
'FileCreateMailReceiver' => 'PhabricatorMailReceiver',
'FileDeletionWorker' => 'PhabricatorWorker',
'FileDownloadConduitAPIMethod' => 'FileConduitAPIMethod',
'FileInfoConduitAPIMethod' => 'FileConduitAPIMethod',
'FileMailReceiver' => 'PhabricatorObjectMailReceiver',

View file

@ -143,6 +143,7 @@ final class PhabricatorFileDataController extends PhabricatorFileController {
$file = id(new PhabricatorFileQuery())
->setViewer($viewer)
->withPHIDs(array($this->phid))
->withIsDeleted(false)
->executeOne();
if (!$file) {

View file

@ -9,6 +9,7 @@ final class PhabricatorFileDeleteController extends PhabricatorFileController {
$file = id(new PhabricatorFileQuery())
->setViewer($viewer)
->withIDs(array($id))
->withIsDeleted(false)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
@ -25,8 +26,15 @@ final class PhabricatorFileDeleteController extends PhabricatorFileController {
}
if ($request->isFormPost()) {
$engine = new PhabricatorDestructionEngine();
$engine->destroyObject($file);
// Mark the file for deletion, save it, and schedule a worker to
// sweep by later and pick it up.
$file->setIsDeleted(true)->save();
PhabricatorWorker::scheduleTask(
'FileDeletionWorker',
array('objectPHID' => $file->getPHID()),
array('priority' => PhabricatorWorker::PRIORITY_BULK));
return id(new AphrontRedirectResponse())->setURI('/file/');
}

View file

@ -15,6 +15,7 @@ final class PhabricatorFileInfoController extends PhabricatorFileController {
$file = id(new PhabricatorFileQuery())
->setViewer($viewer)
->withPHIDs(array($phid))
->withIsDeleted(false)
->executeOne();
if (!$file) {
@ -25,6 +26,7 @@ final class PhabricatorFileInfoController extends PhabricatorFileController {
$file = id(new PhabricatorFileQuery())
->setViewer($viewer)
->withIDs(array($id))
->withIsDeleted(false)
->executeOne();
if (!$file) {
return new Aphront404Response();

View file

@ -36,7 +36,9 @@ final class PhabricatorFileEditEngine
}
protected function newObjectQuery() {
return new PhabricatorFileQuery();
$query = new PhabricatorFileQuery();
$query->withIsDeleted(false);
return $query;
}
protected function getObjectCreateTitleText($object) {

View file

@ -15,6 +15,7 @@ final class PhabricatorFileQuery
private $maxLength;
private $names;
private $isPartial;
private $isDeleted;
private $needTransforms;
private $builtinKeys;
@ -119,6 +120,11 @@ final class PhabricatorFileQuery
return $this;
}
public function withIsDeleted($deleted) {
$this->isDeleted = $deleted;
return $this;
}
public function withNameNgrams($ngrams) {
return $this->withNgramsConstraint(
id(new PhabricatorFileNameNgrams()),
@ -396,6 +402,13 @@ final class PhabricatorFileQuery
(int)$this->isPartial);
}
if ($this->isDeleted !== null) {
$where[] = qsprintf(
$conn,
'isDeleted = %d',
(int)$this->isDeleted);
}
if ($this->builtinKeys !== null) {
$where[] = qsprintf(
$conn,

View file

@ -16,7 +16,9 @@ final class PhabricatorFileSearchEngine
}
public function newQuery() {
return new PhabricatorFileQuery();
$query = new PhabricatorFileQuery();
$query->withIsDeleted(false);
return $query;
}
protected function buildCustomSearchFields() {

View file

@ -59,6 +59,7 @@ final class PhabricatorFile extends PhabricatorFileDAO
protected $isExplicitUpload = 1;
protected $viewPolicy = PhabricatorPolicies::POLICY_USER;
protected $isPartial = 0;
protected $isDeleted = 0;
private $objects = self::ATTACHABLE;
private $objectPHIDs = self::ATTACHABLE;
@ -103,6 +104,7 @@ final class PhabricatorFile extends PhabricatorFileDAO
'mailKey' => 'bytes20',
'isPartial' => 'bool',
'builtinKey' => 'text64?',
'isDeleted' => 'bool',
),
self::CONFIG_KEY_SCHEMA => array(
'key_phid' => null,

View file

@ -0,0 +1,31 @@
<?php
final class FileDeletionWorker extends PhabricatorWorker {
private function loadFile() {
$phid = idx($this->getTaskData(), 'objectPHID');
if (!$phid) {
throw new PhabricatorWorkerPermanentFailureException(
pht('No "%s" in task data.', 'objectPHID'));
}
$file = id(new PhabricatorFileQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withPHIDs(array($phid))
->executeOne();
if (!$file) {
throw new PhabricatorWorkerPermanentFailureException(
pht('File "%s" does not exist.', $phid));
}
return $file;
}
protected function doWork() {
$file = $this->loadFile();
$engine = new PhabricatorDestructionEngine();
$engine->destroyObject($file);
}
}