@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
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Provide more information to users during `git push` while waiting for write locks

Summary:
Ref T13109. Make it slightly more clear what the scope of the write and read locks are, and slightly more clear that we're actively acquiring locks, not just sitting around waiting.

While waiting on another writer, show who we're waiting on so you can walk over to their desk and glare at them.

Test Plan:
Added `sleep(15)` after `willWrite()`. Pushed in two windows. Saw new, more informative messages. In the second window, saw the new guidance:

> # Waiting for hector to finish writing (on device "repo1.local.phacility.net" for 11s)...

Reviewers: asherkin

Reviewed By: asherkin

Subscribers: asherkin

Maniphest Tasks: T13109

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

+84 -8
+52 -8
src/applications/diffusion/protocol/DiffusionRepositoryClusterEngine.php
··· 151 151 152 152 $this->logLine( 153 153 pht( 154 - 'Waiting up to %s second(s) for a cluster read lock on "%s"...', 155 - new PhutilNumber($lock_wait), 154 + 'Acquiring read lock for repository "%s" on device "%s"...', 155 + $repository->getDisplayName(), 156 156 $device->getName())); 157 157 158 158 try { ··· 308 308 309 309 $write_lock->useSpecificConnection($locked_connection); 310 310 311 - $lock_wait = phutil_units('2 minutes in seconds'); 312 - 313 311 $this->logLine( 314 312 pht( 315 - 'Waiting up to %s second(s) for a cluster write lock...', 316 - new PhutilNumber($lock_wait))); 313 + 'Acquiring write lock for repository "%s"...', 314 + $repository->getDisplayName())); 317 315 316 + $lock_wait = phutil_units('2 minutes in seconds'); 318 317 try { 319 318 $start = PhabricatorTime::getNow(); 320 - $write_lock->lock($lock_wait); 321 - $waited = (PhabricatorTime::getNow() - $start); 319 + $step_wait = 1; 322 320 321 + while (true) { 322 + try { 323 + $write_lock->lock((int)floor($step_wait)); 324 + break; 325 + } catch (PhutilLockException $ex) { 326 + $waited = (PhabricatorTime::getNow() - $start); 327 + if ($waited > $lock_wait) { 328 + throw $ex; 329 + } 330 + $this->logActiveWriter($viewer, $repository); 331 + } 332 + 333 + // Wait a little longer before the next message we print. 334 + $step_wait = $step_wait + 0.5; 335 + $step_wait = min($step_wait, 3); 336 + } 337 + 338 + $waited = (PhabricatorTime::getNow() - $start); 323 339 if ($waited) { 324 340 $this->logLine( 325 341 pht( ··· 761 777 $repository->getMonogram(), 762 778 $device->getName())); 763 779 } 780 + } 781 + 782 + private function logActiveWriter( 783 + PhabricatorUser $viewer, 784 + PhabricatorRepository $repository) { 785 + 786 + $writer = PhabricatorRepositoryWorkingCopyVersion::loadWriter( 787 + $repository->getPHID()); 788 + if (!$writer) { 789 + $this->logLine(pht('Waiting on another user to finish writing...')); 790 + return; 791 + } 792 + 793 + $user_phid = $writer->getWriteProperty('userPHID'); 794 + $device_phid = $writer->getWriteProperty('devicePHID'); 795 + $epoch = $writer->getWriteProperty('epoch'); 796 + 797 + $phids = array($user_phid, $device_phid); 798 + $handles = $viewer->loadHandles($phids); 799 + 800 + $duration = (PhabricatorTime::getNow() - $epoch) + 1; 801 + 802 + $this->logLine( 803 + pht( 804 + 'Waiting for %s to finish writing (on device "%s" for %ss)...', 805 + $handles[$user_phid]->getName(), 806 + $handles[$device_phid]->getName(), 807 + new PhutilNumber($duration))); 764 808 } 765 809 766 810 }
+32
src/applications/repository/storage/PhabricatorRepositoryWorkingCopyVersion.php
··· 28 28 ) + parent::getConfiguration(); 29 29 } 30 30 31 + public function getWriteProperty($key, $default = null) { 32 + // The "writeProperties" don't currently get automatically serialized or 33 + // deserialized. Perhaps they should. 34 + try { 35 + $properties = phutil_json_decode($this->writeProperties); 36 + return idx($properties, $key, $default); 37 + } catch (Exception $ex) { 38 + return null; 39 + } 40 + } 41 + 31 42 public static function loadVersions($repository_phid) { 32 43 $version = new self(); 33 44 $conn_w = $version->establishConnection('w'); ··· 42 53 43 54 return $version->loadAllFromArray($rows); 44 55 } 56 + 57 + public static function loadWriter($repository_phid) { 58 + $version = new self(); 59 + $conn_w = $version->establishConnection('w'); 60 + $table = $version->getTableName(); 61 + 62 + // We're forcing this read to go to the master. 63 + $row = queryfx_one( 64 + $conn_w, 65 + 'SELECT * FROM %T WHERE repositoryPHID = %s AND isWriting = 1 66 + LIMIT 1', 67 + $table, 68 + $repository_phid); 69 + 70 + if (!$row) { 71 + return null; 72 + } 73 + 74 + return $version->loadFromArray($row); 75 + } 76 + 45 77 46 78 public static function getReadLock($repository_phid, $device_phid) { 47 79 $repository_hash = PhabricatorHash::digestForIndex($repository_phid);