@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
at upstream/main 142 lines 3.4 kB view raw
1<?php 2 3abstract class DiffusionFileFutureQuery 4 extends DiffusionQuery { 5 6 private $timeout; 7 private $byteLimit; 8 9 private $didHitByteLimit = false; 10 private $didHitTimeLimit = false; 11 12 public static function getConduitParameters() { 13 return array( 14 'timeout' => 'optional int', 15 'byteLimit' => 'optional int', 16 ); 17 } 18 19 public function setTimeout($timeout) { 20 $this->timeout = $timeout; 21 return $this; 22 } 23 24 public function getTimeout() { 25 return $this->timeout; 26 } 27 28 public function setByteLimit($byte_limit) { 29 $this->byteLimit = $byte_limit; 30 return $this; 31 } 32 33 public function getByteLimit() { 34 return $this->byteLimit; 35 } 36 37 final public function getExceededByteLimit() { 38 return $this->didHitByteLimit; 39 } 40 41 final public function getExceededTimeLimit() { 42 return $this->didHitTimeLimit; 43 } 44 45 abstract protected function newQueryFuture(); 46 47 final public function respondToConduitRequest(ConduitAPIRequest $request) { 48 $drequest = $this->getRequest(); 49 50 $timeout = $request->getValue('timeout'); 51 if ($timeout) { 52 $this->setTimeout($timeout); 53 } 54 55 $byte_limit = $request->getValue('byteLimit'); 56 if ($byte_limit) { 57 $this->setByteLimit($byte_limit); 58 } 59 60 $file = $this->execute(); 61 62 $too_slow = (bool)$this->getExceededTimeLimit(); 63 $too_huge = (bool)$this->getExceededByteLimit(); 64 65 $file_phid = null; 66 if (!$too_slow && !$too_huge) { 67 $repository = $drequest->getRepository(); 68 $repository_phid = $repository->getPHID(); 69 70 $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); 71 $file->attachToObject($repository_phid); 72 unset($unguarded); 73 74 $file_phid = $file->getPHID(); 75 } 76 77 return array( 78 'tooSlow' => $too_slow, 79 'tooHuge' => $too_huge, 80 'filePHID' => $file_phid, 81 ); 82 } 83 84 final public function executeInline() { 85 $future = $this->newConfiguredQueryFuture(); 86 list($stdout) = $future->resolvex(); 87 return $stdout; 88 } 89 90 final protected function executeQuery() { 91 $future = $this->newConfiguredQueryFuture(); 92 93 $drequest = $this->getRequest(); 94 95 $name = basename($drequest->getPath()); 96 $relative_ttl = phutil_units('48 hours in seconds'); 97 98 try { 99 $threshold = PhabricatorFileStorageEngine::getChunkThreshold(); 100 $future->setReadBufferSize($threshold); 101 102 $source = id(new PhabricatorExecFutureFileUploadSource()) 103 ->setName($name) 104 ->setRelativeTTL($relative_ttl) 105 ->setViewPolicy(PhabricatorPolicies::POLICY_NOONE) 106 ->setExecFuture($future); 107 108 $byte_limit = $this->getByteLimit(); 109 if ($byte_limit) { 110 $source->setByteLimit($byte_limit); 111 } 112 113 $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); 114 $file = $source->uploadFile(); 115 unset($unguarded); 116 117 } catch (CommandException $ex) { 118 if (!$future->getWasKilledByTimeout()) { 119 throw $ex; 120 } 121 122 $this->didHitTimeLimit = true; 123 $file = null; 124 } catch (PhabricatorFileUploadSourceByteLimitException $ex) { 125 $this->didHitByteLimit = true; 126 $file = null; 127 } 128 129 return $file; 130 } 131 132 private function newConfiguredQueryFuture() { 133 $future = $this->newQueryFuture(); 134 135 if ($this->getTimeout()) { 136 $future->setTimeout($this->getTimeout()); 137 } 138 139 return $future; 140 } 141 142}