Page MenuHomePhabricator

D19247.id46081.diff
No OneTemporary

D19247.id46081.diff

diff --git a/src/applications/diffusion/protocol/DiffusionRepositoryClusterEngine.php b/src/applications/diffusion/protocol/DiffusionRepositoryClusterEngine.php
--- a/src/applications/diffusion/protocol/DiffusionRepositoryClusterEngine.php
+++ b/src/applications/diffusion/protocol/DiffusionRepositoryClusterEngine.php
@@ -151,8 +151,8 @@
$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 @@
$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 @@
}
}
+ 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)));
+ }
+
}
diff --git a/src/applications/repository/storage/PhabricatorRepositoryWorkingCopyVersion.php b/src/applications/repository/storage/PhabricatorRepositoryWorkingCopyVersion.php
--- a/src/applications/repository/storage/PhabricatorRepositoryWorkingCopyVersion.php
+++ b/src/applications/repository/storage/PhabricatorRepositoryWorkingCopyVersion.php
@@ -28,6 +28,17 @@
) + 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 @@
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);

File Metadata

Mime Type
text/plain
Expires
Sat, May 11, 5:12 AM (1 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6275899
Default Alt Text
D19247.id46081.diff (4 KB)

Event Timeline