mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-26 00:32:42 +01:00
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
This commit is contained in:
parent
c8583b016d
commit
859b274970
2 changed files with 84 additions and 8 deletions
|
@ -151,8 +151,8 @@ final class DiffusionRepositoryClusterEngine extends Phobject {
|
|||
|
||||
$this->logLine(
|
||||
pht(
|
||||
'Waiting up to %s second(s) for a cluster read lock on "%s"...',
|
||||
new PhutilNumber($lock_wait),
|
||||
'Acquiring read lock for repository "%s" on device "%s"...',
|
||||
$repository->getDisplayName(),
|
||||
$device->getName()));
|
||||
|
||||
try {
|
||||
|
@ -308,18 +308,34 @@ final class DiffusionRepositoryClusterEngine extends Phobject {
|
|||
|
||||
$write_lock->useSpecificConnection($locked_connection);
|
||||
|
||||
$lock_wait = phutil_units('2 minutes in seconds');
|
||||
|
||||
$this->logLine(
|
||||
pht(
|
||||
'Waiting up to %s second(s) for a cluster write lock...',
|
||||
new PhutilNumber($lock_wait)));
|
||||
'Acquiring write lock for repository "%s"...',
|
||||
$repository->getDisplayName()));
|
||||
|
||||
$lock_wait = phutil_units('2 minutes in seconds');
|
||||
try {
|
||||
$start = PhabricatorTime::getNow();
|
||||
$write_lock->lock($lock_wait);
|
||||
$waited = (PhabricatorTime::getNow() - $start);
|
||||
$step_wait = 1;
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
$write_lock->lock((int)floor($step_wait));
|
||||
break;
|
||||
} catch (PhutilLockException $ex) {
|
||||
$waited = (PhabricatorTime::getNow() - $start);
|
||||
if ($waited > $lock_wait) {
|
||||
throw $ex;
|
||||
}
|
||||
$this->logActiveWriter($viewer, $repository);
|
||||
}
|
||||
|
||||
// Wait a little longer before the next message we print.
|
||||
$step_wait = $step_wait + 0.5;
|
||||
$step_wait = min($step_wait, 3);
|
||||
}
|
||||
|
||||
$waited = (PhabricatorTime::getNow() - $start);
|
||||
if ($waited) {
|
||||
$this->logLine(
|
||||
pht(
|
||||
|
@ -763,4 +779,32 @@ final class DiffusionRepositoryClusterEngine extends Phobject {
|
|||
}
|
||||
}
|
||||
|
||||
private function logActiveWriter(
|
||||
PhabricatorUser $viewer,
|
||||
PhabricatorRepository $repository) {
|
||||
|
||||
$writer = PhabricatorRepositoryWorkingCopyVersion::loadWriter(
|
||||
$repository->getPHID());
|
||||
if (!$writer) {
|
||||
$this->logLine(pht('Waiting on another user to finish writing...'));
|
||||
return;
|
||||
}
|
||||
|
||||
$user_phid = $writer->getWriteProperty('userPHID');
|
||||
$device_phid = $writer->getWriteProperty('devicePHID');
|
||||
$epoch = $writer->getWriteProperty('epoch');
|
||||
|
||||
$phids = array($user_phid, $device_phid);
|
||||
$handles = $viewer->loadHandles($phids);
|
||||
|
||||
$duration = (PhabricatorTime::getNow() - $epoch) + 1;
|
||||
|
||||
$this->logLine(
|
||||
pht(
|
||||
'Waiting for %s to finish writing (on device "%s" for %ss)...',
|
||||
$handles[$user_phid]->getName(),
|
||||
$handles[$device_phid]->getName(),
|
||||
new PhutilNumber($duration)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,6 +28,17 @@ final class PhabricatorRepositoryWorkingCopyVersion
|
|||
) + parent::getConfiguration();
|
||||
}
|
||||
|
||||
public function getWriteProperty($key, $default = null) {
|
||||
// The "writeProperties" don't currently get automatically serialized or
|
||||
// deserialized. Perhaps they should.
|
||||
try {
|
||||
$properties = phutil_json_decode($this->writeProperties);
|
||||
return idx($properties, $key, $default);
|
||||
} catch (Exception $ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static function loadVersions($repository_phid) {
|
||||
$version = new self();
|
||||
$conn_w = $version->establishConnection('w');
|
||||
|
@ -43,6 +54,27 @@ final class PhabricatorRepositoryWorkingCopyVersion
|
|||
return $version->loadAllFromArray($rows);
|
||||
}
|
||||
|
||||
public static function loadWriter($repository_phid) {
|
||||
$version = new self();
|
||||
$conn_w = $version->establishConnection('w');
|
||||
$table = $version->getTableName();
|
||||
|
||||
// We're forcing this read to go to the master.
|
||||
$row = queryfx_one(
|
||||
$conn_w,
|
||||
'SELECT * FROM %T WHERE repositoryPHID = %s AND isWriting = 1
|
||||
LIMIT 1',
|
||||
$table,
|
||||
$repository_phid);
|
||||
|
||||
if (!$row) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $version->loadFromArray($row);
|
||||
}
|
||||
|
||||
|
||||
public static function getReadLock($repository_phid, $device_phid) {
|
||||
$repository_hash = PhabricatorHash::digestForIndex($repository_phid);
|
||||
$device_hash = PhabricatorHash::digestForIndex($device_phid);
|
||||
|
|
Loading…
Reference in a new issue