Changeset View
Changeset View
Standalone View
Standalone View
src/applications/repository/storage/PhabricatorRepository.php
| Show First 20 Lines • Show All 1,903 Lines • ▼ Show 20 Lines | public function getAlmanacServiceURI( | ||||
| PhabricatorUser $viewer, | PhabricatorUser $viewer, | ||||
| array $options) { | array $options) { | ||||
| PhutilTypeSpec::checkMap( | PhutilTypeSpec::checkMap( | ||||
| $options, | $options, | ||||
| array( | array( | ||||
| 'neverProxy' => 'bool', | 'neverProxy' => 'bool', | ||||
| 'protocols' => 'list<string>', | 'protocols' => 'list<string>', | ||||
| 'writable' => 'optional bool', | |||||
| )); | )); | ||||
| $never_proxy = $options['neverProxy']; | $never_proxy = $options['neverProxy']; | ||||
| $protocols = $options['protocols']; | $protocols = $options['protocols']; | ||||
| $writable = idx($options, 'writable', false); | |||||
| $cache_key = $this->getAlmanacServiceCacheKey(); | $cache_key = $this->getAlmanacServiceCacheKey(); | ||||
| if (!$cache_key) { | if (!$cache_key) { | ||||
| return null; | return null; | ||||
| } | } | ||||
| $cache = PhabricatorCaches::getMutableStructureCache(); | $cache = PhabricatorCaches::getMutableStructureCache(); | ||||
| $uris = $cache->getKey($cache_key, false); | $uris = $cache->getKey($cache_key, false); | ||||
| Show All 29 Lines | foreach ($uris as $uri) { | ||||
| if ($local_device && $never_proxy) { | if ($local_device && $never_proxy) { | ||||
| if ($uri['device'] == $local_device) { | if ($uri['device'] == $local_device) { | ||||
| return null; | return null; | ||||
| } | } | ||||
| } | } | ||||
| if (isset($protocol_map[$uri['protocol']])) { | if (isset($protocol_map[$uri['protocol']])) { | ||||
| $results[] = new PhutilURI($uri['uri']); | $results[] = $uri; | ||||
| } | } | ||||
| } | } | ||||
| if (!$results) { | if (!$results) { | ||||
| throw new Exception( | throw new Exception( | ||||
| pht( | pht( | ||||
| 'The Almanac service for this repository is not bound to any '. | 'The Almanac service for this repository is not bound to any '. | ||||
| 'interfaces which support the required protocols (%s).', | 'interfaces which support the required protocols (%s).', | ||||
| Show All 14 Lines | if (count($results) > 1) { | ||||
| 'Repository "%s" is bound to multiple active repository hosts, '. | 'Repository "%s" is bound to multiple active repository hosts, '. | ||||
| 'but this repository does not support cluster synchronization. '. | 'but this repository does not support cluster synchronization. '. | ||||
| 'Declusterize this repository or move it to a service with only '. | 'Declusterize this repository or move it to a service with only '. | ||||
| 'one host.', | 'one host.', | ||||
| $this->getDisplayName())); | $this->getDisplayName())); | ||||
| } | } | ||||
| } | } | ||||
| // If we require a writable device, remove URIs which aren't writable. | |||||
| if ($writable) { | |||||
| foreach ($results as $key => $uri) { | |||||
| if (!$uri['writable']) { | |||||
| unset($results[$key]); | |||||
| } | |||||
| } | |||||
| if (!$results) { | |||||
| throw new Exception( | |||||
| pht( | |||||
| 'This repository ("%s") is not writable with the given '. | |||||
| 'protocols (%s). The Almanac service for this repository has no '. | |||||
| 'writable bindings that support these protocols.', | |||||
| $this->getDisplayName(), | |||||
| implode(', ', $protocols))); | |||||
| } | |||||
| } | |||||
| shuffle($results); | shuffle($results); | ||||
| return head($results); | |||||
| $result = head($results); | |||||
| return $result['uri']; | |||||
| } | } | ||||
| public function supportsSynchronization() { | public function supportsSynchronization() { | ||||
| // TODO: For now, this is only supported for Git. | // TODO: For now, this is only supported for Git. | ||||
| if (!$this->isGit()) { | if (!$this->isGit()) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| public function getAlmanacServiceCacheKey() { | public function getAlmanacServiceCacheKey() { | ||||
| $service_phid = $this->getAlmanacServicePHID(); | $service_phid = $this->getAlmanacServicePHID(); | ||||
| if (!$service_phid) { | if (!$service_phid) { | ||||
| return null; | return null; | ||||
| } | } | ||||
| $repository_phid = $this->getPHID(); | $repository_phid = $this->getPHID(); | ||||
| return "diffusion.repository({$repository_phid}).service({$service_phid})"; | |||||
| $parts = array( | |||||
| "repo({$repository_phid})", | |||||
| "serv({$service_phid})", | |||||
| 'v2', | |||||
| ); | |||||
| return implode('.', $parts); | |||||
| } | } | ||||
| private function buildAlmanacServiceURIs() { | private function buildAlmanacServiceURIs() { | ||||
| $service = $this->loadAlmanacService(); | $service = $this->loadAlmanacService(); | ||||
| if (!$service) { | if (!$service) { | ||||
| return null; | return null; | ||||
| } | } | ||||
| Show All 12 Lines | foreach ($bindings as $binding) { | ||||
| $uri = $this->getClusterRepositoryURIFromBinding($binding); | $uri = $this->getClusterRepositoryURIFromBinding($binding); | ||||
| $protocol = $uri->getProtocol(); | $protocol = $uri->getProtocol(); | ||||
| $device_name = $iface->getDevice()->getName(); | $device_name = $iface->getDevice()->getName(); | ||||
| $uris[] = array( | $uris[] = array( | ||||
| 'protocol' => $protocol, | 'protocol' => $protocol, | ||||
| 'uri' => (string)$uri, | 'uri' => (string)$uri, | ||||
| 'device' => $device_name, | 'device' => $device_name, | ||||
| 'writable' => (bool)$binding->getAlmanacPropertyValue('writable'), | |||||
| ); | ); | ||||
| } | } | ||||
| return $uris; | return $uris; | ||||
| } | } | ||||
| /** | /** | ||||
| * Build a new Conduit client in order to make a service call to this | * Build a new Conduit client in order to make a service call to this | ||||
| Show All 37 Lines | public function newConduitClient( | ||||
| $uri = $this->getAlmanacServiceURI( | $uri = $this->getAlmanacServiceURI( | ||||
| $viewer, | $viewer, | ||||
| array( | array( | ||||
| 'neverProxy' => $never_proxy, | 'neverProxy' => $never_proxy, | ||||
| 'protocols' => array( | 'protocols' => array( | ||||
| 'http', | 'http', | ||||
| 'https', | 'https', | ||||
| ), | ), | ||||
| // At least today, no Conduit call can ever write to a repository, | |||||
| // so it's fine to send anything to a read-only node. | |||||
| 'writable' => false, | |||||
| )); | )); | ||||
| if ($uri === null) { | if ($uri === null) { | ||||
| return null; | return null; | ||||
| } | } | ||||
| $domain = id(new PhutilURI(PhabricatorEnv::getURI('/')))->getDomain(); | $domain = id(new PhutilURI(PhabricatorEnv::getURI('/')))->getDomain(); | ||||
| $client = id(new ConduitClient($uri)) | $client = id(new ConduitClient($uri)) | ||||
| ▲ Show 20 Lines • Show All 569 Lines • Show Last 20 Lines | |||||