feat: Implement custom Updater for object store storage

Signed-off-by: Louis Chemineau <louis@chmn.me>

fix: fix incorrect filesize for object store touch

Signed-off-by: Robin Appelman <robin@icewind.nl>

test: improve version storage test

Signed-off-by: Robin Appelman <robin@icewind.nl>
artonge/feat/implement_custom_updater_for_object_storage-squashed
Louis Chemineau 7 months ago committed by Robin Appelman
parent 7be047a5c0
commit 1a01b3ead8
No known key found for this signature in database
GPG Key ID: 42B69D8A64526EFB
  1. 4
      apps/files_versions/tests/StorageTest.php
  2. 1
      lib/composer/composer/autoload_classmap.php
  3. 1
      lib/composer/composer/autoload_static.php
  4. 2
      lib/private/Files/Cache/Updater.php
  5. 21
      lib/private/Files/ObjectStore/ObjectStoreStorage.php
  6. 41
      lib/private/Files/ObjectStore/ObjectStoreUpdater.php
  7. 4
      lib/public/Files/Cache/IUpdater.php

@ -49,10 +49,10 @@ class StorageTest extends TestCase {
protected function createPastFile(string $path, int $mtime): void {
try {
$file = $this->userFolder->get($path);
$file->putContent((string)$mtime);
} catch (NotFoundException $e) {
$file = $this->userFolder->newFile($path);
$file = $this->userFolder->newFile($path, (string)$mtime);
}
$file->putContent((string)$mtime);
$file->touch($mtime);
}

@ -1648,6 +1648,7 @@ return array(
'OC\\Files\\ObjectStore\\Mapper' => $baseDir . '/lib/private/Files/ObjectStore/Mapper.php',
'OC\\Files\\ObjectStore\\ObjectStoreScanner' => $baseDir . '/lib/private/Files/ObjectStore/ObjectStoreScanner.php',
'OC\\Files\\ObjectStore\\ObjectStoreStorage' => $baseDir . '/lib/private/Files/ObjectStore/ObjectStoreStorage.php',
'OC\\Files\\ObjectStore\\ObjectStoreUpdater' => $baseDir . '/lib/private/Files/ObjectStore/ObjectStoreUpdater.php',
'OC\\Files\\ObjectStore\\PrimaryObjectStoreConfig' => $baseDir . '/lib/private/Files/ObjectStore/PrimaryObjectStoreConfig.php',
'OC\\Files\\ObjectStore\\S3' => $baseDir . '/lib/private/Files/ObjectStore/S3.php',
'OC\\Files\\ObjectStore\\S3ConfigTrait' => $baseDir . '/lib/private/Files/ObjectStore/S3ConfigTrait.php',

@ -1689,6 +1689,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Files\\ObjectStore\\Mapper' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/Mapper.php',
'OC\\Files\\ObjectStore\\ObjectStoreScanner' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/ObjectStoreScanner.php',
'OC\\Files\\ObjectStore\\ObjectStoreStorage' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/ObjectStoreStorage.php',
'OC\\Files\\ObjectStore\\ObjectStoreUpdater' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/ObjectStoreUpdater.php',
'OC\\Files\\ObjectStore\\PrimaryObjectStoreConfig' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/PrimaryObjectStoreConfig.php',
'OC\\Files\\ObjectStore\\S3' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/S3.php',
'OC\\Files\\ObjectStore\\S3ConfigTrait' => __DIR__ . '/../../..' . '/lib/private/Files/ObjectStore/S3ConfigTrait.php',

@ -272,7 +272,7 @@ class Updater implements IUpdater {
*
* @param string $internalPath
*/
private function correctParentStorageMtime($internalPath) {
public function correctParentStorageMtime($internalPath) {
$parentId = $this->cache->getParentId($internalPath);
$parent = dirname($internalPath);
if ($parentId != -1) {

@ -14,6 +14,7 @@ use Icewind\Streams\CountWrapper;
use Icewind\Streams\IteratorDirectory;
use OC\Files\Cache\Cache;
use OC\Files\Cache\CacheEntry;
use OC\Files\Cache\Updater;
use OC\Files\Storage\PolyFill\CopyDirectory;
use OCP\Files\Cache\ICache;
use OCP\Files\Cache\ICacheEntry;
@ -417,7 +418,7 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil
$stat = [
'etag' => $this->getETag($path),
'mimetype' => $mimeType,
'size' => 0,
'size' => 1,
'mtime' => $mtime,
'storage_mtime' => $mtime,
'permissions' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_CREATE,
@ -474,6 +475,7 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil
}
// update stat with new data
$mTime = time();
$oldSize = $stat['size'] ?? 0;
$stat['size'] = (int)$size;
$stat['mtime'] = $mTime;
$stat['storage_mtime'] = $mTime;
@ -571,6 +573,9 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil
}
}
$this->getUpdater()->correctParentStorageMtime($path);
$this->propagator->propagateChange($path, $mTime, $stat['size'] - $oldSize);
return $size;
}
@ -824,4 +829,18 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil
public function setPreserveCacheOnDelete(bool $preserve) {
$this->preserveCacheItemsOnDelete = $preserve;
}
public function getUpdater(?IStorage $storage = null): Updater {
if (!$storage) {
$storage = $this;
}
if (!$storage->instanceOfStorage(self::class)) {
throw new \InvalidArgumentException('Storage is not of the correct class');
}
/** @var self $storage */
if (!isset($storage->updater)) {
$storage->updater = new ObjectStoreUpdater($storage);
}
return $storage->updater;
}
}

@ -0,0 +1,41 @@
<?php
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OC\Files\ObjectStore;
use OC\Files\Cache\Updater;
use OCP\Files\Storage\IStorage;
/**
* Custom wrapper around the Updater for ObjectStoreStorage.
* This wrapper will skip updating the cache in some scenario.
* This is because a lot of cache management is already done in ObjectStoreStorage.
*/
class ObjectStoreUpdater extends Updater {
public function getPropagator() {
return parent::getPropagator();
}
public function propagate($path, $time = null) {
parent::propagate($path, $time);
}
public function update($path, $time = null, ?int $sizeDifference = null) {
// Noop
}
public function remove($path) {
parent::remove($path);
}
public function renameFromStorage(IStorage $sourceStorage, $source, $target) {
parent::renameFromStorage($sourceStorage, $source, $target);
}
public function copyFromStorage(IStorage $sourceStorage, string $source, string $target): void {
parent::copyFromStorage($sourceStorage, $source, $target);
}
}

@ -28,6 +28,7 @@ interface IUpdater {
*
* @param string $path the path of the file to propagate the changes for
* @param int|null $time the timestamp to set as mtime for the parent folders, if left out the current time is used
* @return void
* @since 9.0.0
*/
public function propagate($path, $time = null);
@ -37,6 +38,7 @@ interface IUpdater {
*
* @param string $path
* @param int $time
* @return void
* @since 9.0.0
*/
public function update($path, $time = null, ?int $sizeDifference = null);
@ -45,6 +47,7 @@ interface IUpdater {
* Remove $path from the cache and update the size, etag and mtime of the parent folders
*
* @param string $path
* @return void
* @since 9.0.0
*/
public function remove($path);
@ -55,6 +58,7 @@ interface IUpdater {
* @param IStorage $sourceStorage
* @param string $source
* @param string $target
* @return void
* @since 9.0.0
*/
public function renameFromStorage(IStorage $sourceStorage, $source, $target);

Loading…
Cancel
Save