Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15420229
D19734.id47153.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
3 KB
Referenced Files
None
Subscribers
None
D19734.id47153.diff
View Options
diff --git a/src/applications/repository/storage/PhabricatorRepository.php b/src/applications/repository/storage/PhabricatorRepository.php
--- a/src/applications/repository/storage/PhabricatorRepository.php
+++ b/src/applications/repository/storage/PhabricatorRepository.php
@@ -2010,12 +2010,72 @@
}
}
- shuffle($results);
+ if ($writable) {
+ $results = $this->sortWritableAlmanacServiceURIs($results);
+ } else {
+ shuffle($results);
+ }
$result = head($results);
return $result['uri'];
}
+ private function sortWritableAlmanacServiceURIs(array $results) {
+ // See T13109 for discussion of how this method routes requests.
+
+ // In the absence of other rules, we'll send traffic to devices randomly.
+ // We also want to select randomly among nodes which are equally good
+ // candidates to receive the write, and accomplish that by shuffling the
+ // list up front.
+ shuffle($results);
+
+ $order = array();
+
+ // If some device is currently holding the write lock, send all requests
+ // to that device. We're trying to queue writes on a single device so they
+ // do not need to wait for read synchronization after earlier writes
+ // complete.
+ $writer = PhabricatorRepositoryWorkingCopyVersion::loadWriter(
+ $this->getPHID());
+ if ($writer) {
+ $device_phid = $writer->getWriteProperty('devicePHID');
+ foreach ($results as $key => $result) {
+ if ($result['devicePHID'] === $device_phid) {
+ $order[] = $key;
+ }
+ }
+ }
+
+ // If no device is currently holding the write lock, try to send requests
+ // to a device which is already up to date and will not need to synchronize
+ // before it can accept the write.
+ $versions = PhabricatorRepositoryWorkingCopyVersion::loadVersions(
+ $this->getPHID());
+ if ($versions) {
+ $max_version = (int)max(mpull($versions, 'getRepositoryVersion'));
+
+ $max_devices = array();
+ foreach ($versions as $version) {
+ if ($version->getRepositoryVersion() == $max_version) {
+ $max_devices[] = $version->getDevicePHID();
+ }
+ }
+ $max_devices = array_fuse($max_devices);
+
+ foreach ($results as $key => $result) {
+ if (isset($max_devices[$result['devicePHID']])) {
+ $order[] = $key;
+ }
+ }
+ }
+
+ // Reorder the results, putting any we've selected as preferred targets for
+ // the write at the head of the list.
+ $results = array_select_keys($results, $order) + $results;
+
+ return $results;
+ }
+
public function supportsSynchronization() {
// TODO: For now, this is only supported for Git.
if (!$this->isGit()) {
@@ -2036,7 +2096,7 @@
$parts = array(
"repo({$repository_phid})",
"serv({$service_phid})",
- 'v2',
+ 'v3',
);
return implode('.', $parts);
@@ -2063,12 +2123,14 @@
$uri = $this->getClusterRepositoryURIFromBinding($binding);
$protocol = $uri->getProtocol();
$device_name = $iface->getDevice()->getName();
+ $device_phid = $iface->getDevice()->getPHID();
$uris[] = array(
'protocol' => $protocol,
'uri' => (string)$uri,
'device' => $device_name,
'writable' => (bool)$binding->getAlmanacPropertyValue('writable'),
+ 'devicePHID' => $device_phid,
);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Mar 22, 12:20 PM (2 d, 17 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7533803
Default Alt Text
D19734.id47153.diff (3 KB)
Attached To
Mode
D19734: Try to route cluster writes to nodes which won't need to synchronize first
Attached
Detach File
Event Timeline
Log In to Comment