Differential D21442 Diff 51079 src/applications/diffusion/conduit/DiffusionQueryConduitAPIMethod.php
Changeset View
Changeset View
Standalone View
Standalone View
src/applications/diffusion/conduit/DiffusionQueryConduitAPIMethod.php
| Show First 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | abstract class DiffusionQueryConduitAPIMethod | ||||
| * @{class:DiffusionRequest} and use it. Consolidating this codepath and | * @{class:DiffusionRequest} and use it. Consolidating this codepath and | ||||
| * enforcing @{method:getDiffusionRequest} works when we need it is good. | * enforcing @{method:getDiffusionRequest} works when we need it is good. | ||||
| * | * | ||||
| * @{method:getResult} should be overridden by subclasses as necessary, e.g. | * @{method:getResult} should be overridden by subclasses as necessary, e.g. | ||||
| * there is a common operation across all version control systems that | * there is a common operation across all version control systems that | ||||
| * should occur after @{method:getResult}, like formatting a timestamp. | * should occur after @{method:getResult}, like formatting a timestamp. | ||||
| */ | */ | ||||
| final protected function execute(ConduitAPIRequest $request) { | final protected function execute(ConduitAPIRequest $request) { | ||||
| $drequest = $this->getDiffusionRequest(); | |||||
| // We pass this flag on to prevent proxying of any other Conduit calls | |||||
| // which we need to make in order to respond to this one. Although we | |||||
| // could safely proxy them, we take a big performance hit in the common | |||||
| // case, and doing more proxying wouldn't exercise any additional code so | |||||
| // we wouldn't gain a testability/predictability benefit. | |||||
| $is_cluster_request = $request->getIsClusterRequest(); | |||||
| $drequest->setIsClusterRequest($is_cluster_request); | |||||
| $viewer = $request->getViewer(); | |||||
| $repository = $drequest->getRepository(); | |||||
| // TODO: Allow web UI queries opt out of this if they don't care about | |||||
| // fetching the most up-to-date data? Synchronization can be slow, and a | |||||
| // lot of web reads are probably fine if they're a few seconds out of | |||||
| // date. | |||||
| id(new DiffusionRepositoryClusterEngine()) | |||||
| ->setViewer($viewer) | |||||
| ->setRepository($repository) | |||||
| ->synchronizeWorkingCopyBeforeRead(); | |||||
| return $this->getResult($request); | |||||
| } | |||||
| protected function newConduitCallProxyClient(ConduitAPIRequest $request) { | |||||
| $viewer = $request->getViewer(); | |||||
| $identifier = $request->getValue('repository'); | $identifier = $request->getValue('repository'); | ||||
| if ($identifier === null) { | if ($identifier === null) { | ||||
| $identifier = $request->getValue('callsign'); | $identifier = $request->getValue('callsign'); | ||||
| } | } | ||||
| $drequest = DiffusionRequest::newFromDictionary( | $drequest = DiffusionRequest::newFromDictionary( | ||||
| array( | array( | ||||
| 'user' => $request->getUser(), | 'user' => $viewer, | ||||
| 'repository' => $identifier, | 'repository' => $identifier, | ||||
| 'branch' => $request->getValue('branch'), | 'branch' => $request->getValue('branch'), | ||||
| 'path' => $request->getValue('path'), | 'path' => $request->getValue('path'), | ||||
| 'commit' => $request->getValue('commit'), | 'commit' => $request->getValue('commit'), | ||||
| )); | )); | ||||
| if (!$drequest) { | if (!$drequest) { | ||||
| throw new Exception( | throw new Exception( | ||||
| pht( | pht( | ||||
| 'Repository "%s" is not a valid repository.', | 'Repository "%s" is not a valid repository.', | ||||
| $identifier)); | $identifier)); | ||||
| } | } | ||||
| // Figure out whether we're going to handle this request on this device, | |||||
| // or proxy it to another node in the cluster. | |||||
| // If this is a cluster request and we need to proxy, we'll explode here | |||||
| // to prevent infinite recursion. | |||||
| $is_cluster_request = $request->getIsClusterRequest(); | |||||
| $viewer = $request->getUser(); | |||||
| $repository = $drequest->getRepository(); | $repository = $drequest->getRepository(); | ||||
| $client = $repository->newConduitClient( | |||||
| $viewer, | |||||
| $is_cluster_request); | |||||
| if ($client) { | |||||
| // We're proxying, so just make an intracluster call. | |||||
| return $client->callMethodSynchronous( | |||||
| $this->getAPIMethodName(), | |||||
| $request->getAllParameters()); | |||||
| } else { | |||||
| // We pass this flag on to prevent proxying of any other Conduit calls | $client = $repository->newConduitClientForRequest($request); | ||||
| // which we need to make in order to respond to this one. Although we | if ($client) { | ||||
| // could safely proxy them, we take a big performance hit in the common | return $client; | ||||
| // case, and doing more proxying wouldn't exercise any additional code so | } | ||||
| // we wouldn't gain a testability/predictability benefit. | |||||
| $drequest->setIsClusterRequest($is_cluster_request); | |||||
| $this->setDiffusionRequest($drequest); | $this->setDiffusionRequest($drequest); | ||||
| // TODO: Allow web UI queries opt out of this if they don't care about | return null; | ||||
| // fetching the most up-to-date data? Synchronization can be slow, and a | |||||
| // lot of web reads are probably fine if they're a few seconds out of | |||||
| // date. | |||||
| id(new DiffusionRepositoryClusterEngine()) | |||||
| ->setViewer($viewer) | |||||
| ->setRepository($repository) | |||||
| ->synchronizeWorkingCopyBeforeRead(); | |||||
| return $this->getResult($request); | |||||
| } | |||||
| } | } | ||||
| protected function getResult(ConduitAPIRequest $request) { | protected function getResult(ConduitAPIRequest $request) { | ||||
| $repository = $this->getRepository($request); | $repository = $this->getRepository($request); | ||||
| $result = null; | $result = null; | ||||
| switch ($repository->getVersionControlSystem()) { | switch ($repository->getVersionControlSystem()) { | ||||
| case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: | case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: | ||||
| $result = $this->getGitResult($request); | $result = $this->getGitResult($request); | ||||
| Show All 15 Lines | |||||