When cluster.databases is configured, read the master connection from it

Summary:
Ref T4571. Ref T10759. Ref T10758. This isn't complete, but gets most of the job done:

  - When `cluster.databases` is set up, most things ignore `mysql.host` now.
  - You can `bin/storage upgrade` and stuff works.
  - You can browse around in the web UI and stuff works.

There's still a lot of weird tricky stuff to navigate, and this has real no advantages over configuring a single server yet (no automatic failover, etc).

Test Plan:
  - Configured `cluster.databases` to point at my `t1.micro` hosts in EC2 (master + replica).
  - Ran `bin/storage upgrade`, got a new install setup on them properly.
  - Survived setup warnings, browsed around.
  - Switched back to local config, ran `bin/storage upgrade`, browsed around, went through setup checks.
  - Intentionally broke config (bad hosts, no masters) and things seemed to react reasonably well.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T4571, T10758, T10759

Differential Revision: https://secure.phabricator.com/D15668
This commit is contained in:
epriestley
2016-04-09 19:46:42 -07:00
parent 0439645d5b
commit 6a4a9bb2d2
4 changed files with 129 additions and 64 deletions

View File

@@ -239,7 +239,7 @@ final class PhabricatorDatabaseRef
continue;
}
$conn = $ref->newConnection();
$conn = $ref->newManagementConnection();
$t_start = microtime(true);
try {
@@ -303,18 +303,69 @@ final class PhabricatorDatabaseRef
return $refs;
}
protected function newConnection() {
public function newManagementConnection() {
return $this->newConnection(
array(
'retries' => 0,
'timeout' => 3,
));
}
public function newApplicationConnection($database) {
return $this->newConnection(
array(
'database' => $database,
));
}
public static function getMasterDatabaseRef() {
$refs = self::loadAll();
if (!$refs) {
$conf = PhabricatorEnv::newObjectFromConfig(
'mysql.configuration-provider',
array(null, 'w', null));
return id(new self())
->setHost($conf->getHost())
->setPort($conf->getPort())
->setUser($conf->getUser())
->setPass($conf->getPassword())
->setIsMaster(true);
}
$master = null;
foreach ($refs as $ref) {
if ($ref->getDisabled()) {
continue;
}
if ($ref->getIsMaster()) {
return $ref;
}
}
return null;
}
private function newConnection(array $options) {
$spec = $options + array(
'user' => $this->getUser(),
'pass' => $this->getPass(),
'host' => $this->getHost(),
'port' => $this->getPort(),
'database' => null,
'retries' => 3,
'timeout' => 15,
);
// TODO: Remove this once the MySQL connector has proper support
// for it, see T6710.
ini_set('mysql.connect_timeout', $spec['timeout']);
return PhabricatorEnv::newObjectFromConfig(
'mysql.implementation',
array(
array(
'user' => $this->getUser(),
'pass' => $this->getPass(),
'host' => $this->getHost(),
'port' => $this->getPort(),
'database' => null,
'retries' => 0,
),
$spec,
));
}