@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

Strip some obsolete code out of Drydock

Summary:
Ref T9252. This simplifies some Drydock code.

Most of this code relates to the old notion of Drydock being able to enumerate all the tasks it needs to complete in order to acquire a lease. The code has stepped back from this, since it's unnecessary, the queue is more powerful than it used to be, and it would be a lot of work to keep track of.

The ~only thing that should ever wait for leases in modern code is `bin/drydock lease`, and it's fine for it to just sit there sleeping, so this just does that.

This reduces the granularity of logging, but I'll address that separately in future logging-focused changes.

Test Plan: Used `bin/drydock lease` to acquire a lease, saw it acquire cleanly.

Reviewers: hach-que, chad

Reviewed By: chad

Maniphest Tasks: T9252

Differential Revision: https://secure.phabricator.com/D14147

+30 -156
+2
resources/sql/autopatches/20150923.drydock.taskid.1.sql
··· 1 + ALTER TABLE {$NAMESPACE}_drydock.drydock_lease 2 + DROP taskID;
-2
src/__phutil_library_map__.php
··· 812 812 'DrydockBlueprintListController' => 'applications/drydock/controller/DrydockBlueprintListController.php', 813 813 'DrydockBlueprintPHIDType' => 'applications/drydock/phid/DrydockBlueprintPHIDType.php', 814 814 'DrydockBlueprintQuery' => 'applications/drydock/query/DrydockBlueprintQuery.php', 815 - 'DrydockBlueprintScopeGuard' => 'applications/drydock/util/DrydockBlueprintScopeGuard.php', 816 815 'DrydockBlueprintSearchEngine' => 'applications/drydock/query/DrydockBlueprintSearchEngine.php', 817 816 'DrydockBlueprintTransaction' => 'applications/drydock/storage/DrydockBlueprintTransaction.php', 818 817 'DrydockBlueprintTransactionQuery' => 'applications/drydock/query/DrydockBlueprintTransactionQuery.php', ··· 4538 4537 'DrydockBlueprintListController' => 'DrydockBlueprintController', 4539 4538 'DrydockBlueprintPHIDType' => 'PhabricatorPHIDType', 4540 4539 'DrydockBlueprintQuery' => 'DrydockQuery', 4541 - 'DrydockBlueprintScopeGuard' => 'Phobject', 4542 4540 'DrydockBlueprintSearchEngine' => 'PhabricatorApplicationSearchEngine', 4543 4541 'DrydockBlueprintTransaction' => 'PhabricatorApplicationTransaction', 4544 4542 'DrydockBlueprintTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
+1 -34
src/applications/drydock/blueprint/DrydockBlueprintImplementation.php
··· 8 8 */ 9 9 abstract class DrydockBlueprintImplementation extends Phobject { 10 10 11 - private $activeResource; 12 - private $activeLease; 13 - 14 11 abstract public function getType(); 15 12 16 13 abstract public function isEnabled(); ··· 265 262 * @task log 266 263 */ 267 264 protected function log($message) { 268 - self::writeLog( 269 - $this->activeResource, 270 - $this->activeLease, 271 - $message); 265 + self::writeLog(null, null, $message); 272 266 } 273 267 274 268 ··· 320 314 // Pre-allocate the resource PHID. 321 315 $resource->setPHID($resource->generatePHID()); 322 316 323 - $this->activeResource = $resource; 324 - 325 - $this->log( 326 - pht( 327 - "Blueprint '%s': Created New Template", 328 - get_class($this))); 329 - 330 317 return $resource; 331 318 } 332 319 ··· 347 334 // TODO: Permanent failure. 348 335 throw new Exception(pht('Lease in bad state.')); 349 336 } 350 - } 351 - 352 - private function pushActiveScope( 353 - DrydockResource $resource = null, 354 - DrydockLease $lease = null) { 355 - 356 - if (($this->activeResource !== null) || 357 - ($this->activeLease !== null)) { 358 - throw new Exception(pht('There is already an active resource or lease!')); 359 - } 360 - 361 - $this->activeResource = $resource; 362 - $this->activeLease = $lease; 363 - 364 - return new DrydockBlueprintScopeGuard($this); 365 - } 366 - 367 - public function popActiveScope() { 368 - $this->activeResource = null; 369 - $this->activeLease = null; 370 337 } 371 338 372 339 }
+27 -60
src/applications/drydock/storage/DrydockLease.php
··· 9 9 protected $ownerPHID; 10 10 protected $attributes = array(); 11 11 protected $status = DrydockLeaseStatus::STATUS_PENDING; 12 - protected $taskID; 13 12 14 13 private $resource = self::ATTACHABLE; 15 14 private $releaseOnDestruction; ··· 64 63 'status' => 'uint32', 65 64 'until' => 'epoch?', 66 65 'resourceType' => 'text128', 67 - 'taskID' => 'id?', 68 66 'ownerPHID' => 'phid?', 69 67 'resourceID' => 'id?', 70 68 ), ··· 108 106 return ($this->resource !== null); 109 107 } 110 108 111 - public function loadResource() { 112 - return id(new DrydockResource())->loadOneWhere( 113 - 'id = %d', 114 - $this->getResourceID()); 115 - } 116 - 117 109 public function queueForActivation() { 118 110 if ($this->getID()) { 119 111 throw new Exception( 120 112 pht('Only new leases may be queued for activation!')); 121 113 } 122 114 123 - $this->setStatus(DrydockLeaseStatus::STATUS_PENDING); 124 - $this->save(); 115 + $this 116 + ->setStatus(DrydockLeaseStatus::STATUS_PENDING) 117 + ->save(); 125 118 126 119 $task = PhabricatorWorker::scheduleTask( 127 120 'DrydockAllocatorWorker', ··· 131 124 array( 132 125 'objectPHID' => $this->getPHID(), 133 126 )); 134 - 135 - // NOTE: Scheduling the task might execute it in-process, if we're running 136 - // from a CLI script. Reload the lease to make sure we have the most 137 - // up-to-date information. Normally, this has no effect. 138 - $this->reload(); 139 - 140 - $this->setTaskID($task->getID()); 141 - $this->save(); 142 127 143 128 return $this; 144 129 } ··· 161 146 } 162 147 } 163 148 164 - public static function waitForLeases(array $leases) { 165 - assert_instances_of($leases, __CLASS__); 166 - 167 - $task_ids = array_filter(mpull($leases, 'getTaskID')); 168 - 169 - PhabricatorWorker::waitForTasks($task_ids); 170 - 171 - $unresolved = $leases; 149 + public function waitUntilActive() { 172 150 while (true) { 173 - foreach ($unresolved as $key => $lease) { 174 - $lease->reload(); 175 - switch ($lease->getStatus()) { 176 - case DrydockLeaseStatus::STATUS_ACTIVE: 177 - unset($unresolved[$key]); 178 - break; 179 - case DrydockLeaseStatus::STATUS_RELEASED: 180 - throw new Exception(pht('Lease has already been released!')); 181 - case DrydockLeaseStatus::STATUS_EXPIRED: 182 - throw new Exception(pht('Lease has already expired!')); 183 - case DrydockLeaseStatus::STATUS_BROKEN: 184 - throw new Exception(pht('Lease has been broken!')); 185 - case DrydockLeaseStatus::STATUS_PENDING: 186 - case DrydockLeaseStatus::STATUS_ACQUIRED: 187 - break; 188 - default: 189 - throw new Exception(pht('Unknown status??')); 190 - } 151 + $lease = $this->reload(); 152 + if (!$lease) { 153 + throw new Exception(pht('Failed to reload lease.')); 191 154 } 192 155 193 - if ($unresolved) { 194 - sleep(1); 195 - } else { 196 - break; 156 + $status = $lease->getStatus(); 157 + 158 + switch ($status) { 159 + case DrydockLeaseStatus::STATUS_ACTIVE: 160 + return; 161 + case DrydockLeaseStatus::STATUS_RELEASED: 162 + throw new Exception(pht('Lease has already been released!')); 163 + case DrydockLeaseStatus::STATUS_EXPIRED: 164 + throw new Exception(pht('Lease has already expired!')); 165 + case DrydockLeaseStatus::STATUS_BROKEN: 166 + throw new Exception(pht('Lease has been broken!')); 167 + case DrydockLeaseStatus::STATUS_PENDING: 168 + case DrydockLeaseStatus::STATUS_ACQUIRED: 169 + break; 170 + default: 171 + throw new Exception( 172 + pht( 173 + 'Lease has unknown status "%s".', 174 + $status)); 197 175 } 198 - } 199 176 200 - foreach ($leases as $lease) { 201 - $lease->attachResource($lease->loadResource()); 177 + sleep(1); 202 178 } 203 - } 204 - 205 - public function waitUntilActive() { 206 - if (!$this->getID()) { 207 - $this->queueForActivation(); 208 - } 209 - 210 - self::waitForLeases(array($this)); 211 - return $this; 212 179 } 213 180 214 181 public function setActivateWhenAcquired($activate) {
-15
src/applications/drydock/util/DrydockBlueprintScopeGuard.php
··· 1 - <?php 2 - 3 - final class DrydockBlueprintScopeGuard extends Phobject { 4 - 5 - private $blueprint; 6 - 7 - public function __construct(DrydockBlueprintImplementation $blueprint) { 8 - $this->blueprint = $blueprint; 9 - } 10 - 11 - public function __destruct() { 12 - $this->blueprint->popActiveScope(); 13 - } 14 - 15 - }
-45
src/infrastructure/daemon/workers/PhabricatorWorker.php
··· 157 157 } 158 158 159 159 160 - /** 161 - * Wait for tasks to complete. 162 - * 163 - * @param list<int> List of queued task IDs to wait for. 164 - * @return void 165 - */ 166 - final public static function waitForTasks(array $task_ids) { 167 - if (!$task_ids) { 168 - return; 169 - } 170 - 171 - $task_table = new PhabricatorWorkerActiveTask(); 172 - 173 - $waiting = array_fuse($task_ids); 174 - while ($waiting) { 175 - $conn_w = $task_table->establishConnection('w'); 176 - 177 - // Check if any of the tasks we're waiting on are still queued. If they 178 - // are not, we're done waiting. 179 - $row = queryfx_one( 180 - $conn_w, 181 - 'SELECT COUNT(*) N FROM %T WHERE id IN (%Ld)', 182 - $task_table->getTableName(), 183 - $waiting); 184 - if (!$row['N']) { 185 - // Nothing is queued anymore. Stop waiting. 186 - break; 187 - } 188 - 189 - // We were not successful in leasing anything. Sleep for a bit and 190 - // see if we have better luck later. 191 - sleep(1); 192 - } 193 - 194 - $tasks = id(new PhabricatorWorkerArchiveTaskQuery()) 195 - ->withIDs($task_ids) 196 - ->execute(); 197 - 198 - foreach ($tasks as $task) { 199 - if ($task->getResult() != PhabricatorWorkerArchiveTask::RESULT_SUCCESS) { 200 - throw new Exception(pht('Task %d failed!', $task->getID())); 201 - } 202 - } 203 - } 204 - 205 160 public function renderForDisplay(PhabricatorUser $viewer) { 206 161 return null; 207 162 }