mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-21 04:50:55 +01:00
When file transforms race and lose, accept defeat gracefully
Summary: Fixes T8277. Transforming files can race; resolve the race after we lose. Test Plan: - Added `sleep(10)` near the bottom of the transform controller. - Transformed a file in two browser windows at the same time; got something like this (exception corresponds to the loser of the race): {F412526} - Applied patch. - Repeated process, got this: {F412527} Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T8277 Differential Revision: https://secure.phabricator.com/D12965
This commit is contained in:
parent
a50de8958e
commit
d70ca6b7c8
1 changed files with 25 additions and 8 deletions
|
@ -30,11 +30,7 @@ final class PhabricatorFileTransformController
|
||||||
}
|
}
|
||||||
|
|
||||||
$transform = $request->getURIData('transform');
|
$transform = $request->getURIData('transform');
|
||||||
$xform = id(new PhabricatorTransformedFile())
|
$xform = $this->loadTransform($source_phid, $transform);
|
||||||
->loadOneWhere(
|
|
||||||
'originalPHID = %s AND transform = %s',
|
|
||||||
$source_phid,
|
|
||||||
$transform);
|
|
||||||
|
|
||||||
if ($xform) {
|
if ($xform) {
|
||||||
if ($is_regenerate) {
|
if ($is_regenerate) {
|
||||||
|
@ -80,8 +76,20 @@ final class PhabricatorFileTransformController
|
||||||
$xform = id(new PhabricatorTransformedFile())
|
$xform = id(new PhabricatorTransformedFile())
|
||||||
->setOriginalPHID($source_phid)
|
->setOriginalPHID($source_phid)
|
||||||
->setTransform($transform)
|
->setTransform($transform)
|
||||||
->setTransformedPHID($xformed_file->getPHID())
|
->setTransformedPHID($xformed_file->getPHID());
|
||||||
->save();
|
|
||||||
|
try {
|
||||||
|
$xform->save();
|
||||||
|
} catch (AphrontDuplicateKeyQueryException $ex) {
|
||||||
|
// If we collide when saving, we've raced another endpoint which was
|
||||||
|
// transforming the same file. Just throw our work away and use that
|
||||||
|
// transform instead.
|
||||||
|
$this->destroyTransform($xform);
|
||||||
|
$xform = $this->loadTransform($source_phid, $transform);
|
||||||
|
if (!$xform) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $this->buildTransformedFileResponse($xform);
|
return $this->buildTransformedFileResponse($xform);
|
||||||
}
|
}
|
||||||
|
@ -113,7 +121,9 @@ final class PhabricatorFileTransformController
|
||||||
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||||
|
|
||||||
if (!$file) {
|
if (!$file) {
|
||||||
$xform->delete();
|
if ($xform->getID()) {
|
||||||
|
$xform->delete();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$engine->destroyObject($file);
|
$engine->destroyObject($file);
|
||||||
}
|
}
|
||||||
|
@ -121,4 +131,11 @@ final class PhabricatorFileTransformController
|
||||||
unset($unguarded);
|
unset($unguarded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function loadTransform($source_phid, $transform) {
|
||||||
|
return id(new PhabricatorTransformedFile())->loadOneWhere(
|
||||||
|
'originalPHID = %s AND transform = %s',
|
||||||
|
$source_phid,
|
||||||
|
$transform);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue