Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/Model/Project.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ protected function getMetadata(): ?array
*/
public function exists(): bool
{
return !empty($this->getDomain());
return (!empty($this->getDomain()))
&& $this->repository->checkReplication($this->getBasicInfo()['dbName']);
}

/**
Expand Down
29 changes: 29 additions & 0 deletions src/Repository/GlobalContribsRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public function globalEditCounts(User $user): ?array

// Pre-populate all projects' metadata, to prevent each project call from fetching it.
$this->caProject->getRepository()->getAll();
$this->checkReplicationAllProjects();

// Compile the output.
$out = [];
Expand Down Expand Up @@ -117,6 +118,34 @@ protected function globalEditCountsFromCentralAuth(User $user): ?array
return $this->setCache($cacheKey, $out);
}

/**
* Get, slice by slice, the list of projects that are actually replicated.
* Takes about 0.5s per slice.
* @return bool[] Keyed by database name, all values are true.
*/
public function checkReplicationAllProjects(): array
{
$cacheKey = $this->getCacheKey("global_replication_check");
if ($this->cache->hasItem($cacheKey)) {
return $this->cache->getItem($cacheKey)->get();
}
$result = [];
$exists = true;
$i = 0;
$sql = "SELECT DISTINCT table_schema
FROM information_schema.tables";
while ($exists) {
$i += 1;
try {
$queryResult = $this->executeProjectsQuery("s$i", $sql)->fetchFirstColumn();
$result = array_merge($result, $queryResult);
} catch (\Throwable) {
$exists = false;
}
}
return $this->setCache($cacheKey, $result, 'PT1H');
}

/**
* Loop through the given dbNames and create Project objects for each.
* @param array $dbNames
Expand Down
41 changes: 41 additions & 0 deletions src/Repository/ProjectRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,47 @@ public function getOne(string $project): ?array
return $this->setCache($cacheKey, $basicInfo, 'PT1H');
}

/**
* Is this project actually replicated? Sometimes projets aren't,
* despite being listed in meta_p.wiki. See T322466.
* @param string $project Database name, without _p.
* @return bool
*/
public function checkReplication(string $project): bool
{
if ('' == $project) {
// This means we failed to getBasicInfo. Let's try and AGF.
// Plus, keeps tests from breaking down.
return true;
}
$cacheKey = $this->getCacheKey($project, "replication_check");
if ($this->cache->hasItem($cacheKey)) {
return $this->cache->getItem($cacheKey)->get();
}
// GlobalContribs preloads replication checks for *all* projects
$allProjectsCacheKey = $this->getCacheKey('', "global_replication_check");
if ($this->cache->hasItem($allProjectsCacheKey)) {
$globalReplicationChecks = $this->cache->getItem($allProjectsCacheKey)->get();
return array_key_exists($project, $globalReplicationChecks);
}
$dbList = $this->getDbList();
if (!array_key_exists($project, $dbList)) {
$result = false;
} else {
$dbSlice = $dbList[$project];
$sql = "SELECT 1
FROM information_schema.tables
WHERE table_schema = :project
LIMIT 1";
$queryResult = $this->executeProjectsQuery($dbSlice, $sql, [
'project' => $project . "_p",
])->fetchAssociative();
$result = (1 == count($queryResult));
}
// Cache for 1h and return
return $this->setCache($cacheKey, $result, 'PT1H'); // feels long to me, but as long as getOne
}

/**
* Get metadata about a project, including the 'dbName', 'url' and 'lang'
*
Expand Down
2 changes: 2 additions & 0 deletions tests/Model/GlobalContribsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ public function testGlobalEdits(): void
'dbName' => 'wiki1',
'url' => 'https://wiki1.example.org',
]);
$wiki1Repo->method('checkReplication')
->willReturn(true);
$wiki1 = new Project('wiki1');
$wiki1->setRepository($wiki1Repo);

Expand Down
2 changes: 2 additions & 0 deletions tests/TestAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ public function getProjectRepo(): MockObject
'dbName' => 'test_wiki',
'lang' => 'en',
]);
$repo->method('checkReplication')
->willReturn(true);
return $repo;
}

Expand Down
Loading