1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-10 00:42:41 +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:
epriestley 2018-03-21 17:51:14 -07:00
parent c8583b016d
commit 859b274970
2 changed files with 84 additions and 8 deletions

View file

@ -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)));
}
}

View file

@ -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);