-
-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[wip] Filecache chunking #43576
[wip] Filecache chunking #43576
Conversation
icewind1991
commented
Feb 14, 2024
•
edited
Loading
edited
- block queries to filecache tables that don't go through the sharding logic
- allow getting a query builder for the filecache tables when provided a storage id to select a shard
- probably not going to expose this to apps and leave it internal for the cache handling
- provide methods for querying by fileid without known storage
928fe31
to
367ba8b
Compare
367ba8b
to
c77f583
Compare
@@ -693,6 +717,7 @@ | |||
* @return $this This QueryBuilder instance. | |||
*/ | |||
public function from($from, $alias = null) { | |||
$this->checkTableAccess($from); |
Check failure
Code scanning / Psalm
ImplicitToStringCast Error
} | ||
|
||
/** | ||
* @param List<int> $storages |
Check failure
Code scanning / Psalm
UndefinedDocblockClass Error
} | ||
|
||
/** | ||
* @param List<int> $storages |
Check failure
Code scanning / Psalm
MismatchingDocblockParamType Error
|
||
/** | ||
* @param List<int> $storages | ||
* @return array<int, List<int>> |
Check failure
Code scanning / Psalm
UndefinedDocblockClass Error
* The results from the callback will be combined and returned | ||
* | ||
* @template T | ||
* @param List<int> $storages |
Check failure
Code scanning / Psalm
UndefinedDocblockClass Error
if (in_array('owner', $requestedFields) || in_array('share_with', $requestedFields) || in_array('share_type', $requestedFields)) { | ||
$this->equipQueryForShares($query); | ||
} | ||
$rawEntries = $this->cacheDatabase->queryStorages($storageIds, function(CacheQueryBuilder $builder, $storages) use ($requestedFields, $searchQuery, $cachesByStorage) { |
Check failure
Code scanning / Psalm
InvalidArgument Error
$this->equipQueryForShares($query); | ||
} | ||
$rawEntries = $this->cacheDatabase->queryStorages($storageIds, function(CacheQueryBuilder $builder, $storages) use ($requestedFields, $searchQuery, $cachesByStorage) { | ||
$cachesForShard = array_map(fn (int $storage) => $cachesByStorage[$storage], $storages); |
Check failure
Code scanning / Psalm
InvalidArgument Error
|
||
return $list; | ||
return $this->cacheDatabase->queryStorages($storageIds, function(CacheQueryBuilder $qb, array $storages) use ($fileIdsByStorage) { |
Check failure
Code scanning / Psalm
InvalidArgument Error
return $this->cacheDatabase->queryStorages($storageIds, function(CacheQueryBuilder $qb, array $storages) use ($fileIdsByStorage) { | ||
$fileIds = []; | ||
foreach ($storages as $storage) { | ||
$fileIds += $fileIdsByStorage[$storage]; | ||
} | ||
|
||
$qb->select('file_id', 'json', 'sync_token')->from(self::TABLE_METADATA); | ||
$qb->where( | ||
$qb->expr()->in('file_id', $qb->createNamedParameter($fileIds, IQueryBuilder::PARAM_INT_ARRAY)) | ||
); | ||
|
||
$list = []; | ||
$result = $qb->executeQuery(); | ||
while ($data = $result->fetch()) { | ||
$fileId = (int) $data['file_id']; | ||
$metadata = new FilesMetadata($fileId); | ||
try { | ||
$metadata->importFromDatabase($data); | ||
} catch (FilesMetadataNotFoundException) { | ||
continue; | ||
} | ||
$list[$fileId] = $metadata; | ||
} | ||
return $list; | ||
}); |
Check failure
Code scanning / Psalm
InvalidArgument Error
f06b5b8
to
6d4e9c0
Compare
@@ -53,7 +56,8 @@ | |||
* @throws Exception | |||
*/ | |||
public function store(IFilesMetadata $filesMetadata): void { | |||
$qb = $this->dbConnection->getQueryBuilder(); | |||
$file = $this->cacheDatabase->getByFileId($filesMetadata->getFileId()); |
Check failure
Code scanning / Psalm
UndefinedMethod Error
@@ -72,7 +76,12 @@ | |||
*/ | |||
public function getMetadataFromFileId(int $fileId): IFilesMetadata { | |||
try { | |||
$qb = $this->dbConnection->getQueryBuilder(); | |||
$file = $this->cacheDatabase->getByFileId($fileId); |
Check failure
Code scanning / Psalm
UndefinedMethod Error
$list[$fileId] = $metadata; | ||
public function getMetadataFromFileIds(array $fileIds, array $storageIds = []): array { | ||
if (!$storageIds) { | ||
$files = $this->cacheDatabase->getByFileIds($fileIds); |
Check failure
Code scanning / Psalm
UndefinedMethod Error
$qb->delete(self::TABLE_METADATA) | ||
->where($qb->expr()->eq('file_id', $qb->createNamedParameter($fileId, IQueryBuilder::PARAM_INT))); | ||
$qb->executeStatement(); | ||
$file = $this->cacheDatabase->getByFileId($fileId); |
Check failure
Code scanning / Psalm
UndefinedMethod Error
@@ -155,7 +183,8 @@ | |||
* @throws Exception | |||
*/ | |||
public function updateMetadata(IFilesMetadata $filesMetadata): int { | |||
$qb = $this->dbConnection->getQueryBuilder(); | |||
$file = $this->cacheDatabase->getByFileId($filesMetadata->getFileId()); |
Check failure
Code scanning / Psalm
UndefinedMethod Error
6d4e9c0
to
a5d7410
Compare
Signed-off-by: Robin Appelman <[email protected]>
Signed-off-by: Robin Appelman <[email protected]>
Signed-off-by: Robin Appelman <[email protected]>
8aa41af
to
adc3d9c
Compare
Signed-off-by: Robin Appelman <[email protected]>
Signed-off-by: Robin Appelman <[email protected]>
not as performant but compatible with sharding Signed-off-by: Robin Appelman <[email protected]>
Signed-off-by: Robin Appelman <[email protected]>
adc3d9c
to
4c6aabf
Compare
@@ -723,26 +718,26 @@ | |||
$retryLimit = 4; | |||
for ($i = 1; $i <= $retryLimit; $i++) { | |||
try { | |||
$this->connection->beginTransaction(); | |||
$this->cacheDb->beginTransaction(); |
Check failure
Code scanning / Psalm
TooFewArguments Error
@@ -723,26 +718,26 @@ | |||
$retryLimit = 4; | |||
for ($i = 1; $i <= $retryLimit; $i++) { | |||
try { | |||
$this->connection->beginTransaction(); | |||
$this->cacheDb->beginTransaction(); |
Check failure
Code scanning / Psalm
TooFewArguments Error
throw $e; | ||
} catch (RetryableException $e) { | ||
// Simply throw if we already retried 4 times. | ||
if ($i === $retryLimit) { | ||
throw $e; | ||
} | ||
|
||
$this->connection->rollBack(); | ||
$this->cacheDb->rollBack(); |
Check failure
Code scanning / Psalm
TooFewArguments Error
throw $e; | ||
} catch (RetryableException $e) { | ||
// Simply throw if we already retried 4 times. | ||
if ($i === $retryLimit) { | ||
throw $e; | ||
} | ||
|
||
$this->connection->rollBack(); | ||
$this->cacheDb->rollBack(); |
Check failure
Code scanning / Psalm
TooFewArguments Error
|
||
// Sleep a bit to give some time to the other transaction to finish. | ||
usleep(100 * 1000 * $i); | ||
} | ||
} | ||
} else { | ||
$this->connection->beginTransaction(); | ||
$this->cacheDb->beginTransaction(); |
Check failure
Code scanning / Psalm
TooFewArguments Error
|
||
// Sleep a bit to give some time to the other transaction to finish. | ||
usleep(100 * 1000 * $i); | ||
} | ||
} | ||
} else { | ||
$this->connection->beginTransaction(); | ||
$this->cacheDb->beginTransaction(); |
Check failure
Code scanning / Psalm
TooFewArguments Error
foreach ($shares as $share) { | ||
if (isset($files[$share->getNodeId()])) { | ||
$cacheItem = $files[$share->getNodeId()]; | ||
if ($this->isAccessibleResult($cacheItem->getData())) { |
Check failure
Code scanning / Psalm
UndefinedInterfaceMethod Error