diff options
author | Simon L <szaimen@e.mail.de> | 2022-11-28 19:29:08 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-28 19:29:08 +0100 |
commit | c4157e4653e7bfa55f5c0fa2e82e12b5d120fa56 (patch) | |
tree | 8d54d5676f73a51725a91f02da0473bd6a7f9f58 /lib | |
parent | cd7cec587ed7048b6a5536d69bce904f9eadc598 (diff) | |
parent | 7c4ceb444cb22f519cd30af5cd22304b960c8818 (diff) | |
download | nextcloud-server-c4157e4653e7bfa55f5c0fa2e82e12b5d120fa56.tar.gz nextcloud-server-c4157e4653e7bfa55f5c0fa2e82e12b5d120fa56.zip |
Merge pull request #34941 from nextcloud/enh/33654/add-group-displayname-cache
Add a Group display name cache
Diffstat (limited to 'lib')
-rw-r--r-- | lib/composer/composer/autoload_classmap.php | 2 | ||||
-rw-r--r-- | lib/composer/composer/autoload_static.php | 2 | ||||
-rw-r--r-- | lib/private/Group/DisplayNameCache.php | 87 | ||||
-rw-r--r-- | lib/private/Group/Group.php | 2 | ||||
-rw-r--r-- | lib/private/Group/Manager.php | 17 | ||||
-rw-r--r-- | lib/private/Server.php | 3 | ||||
-rw-r--r-- | lib/public/Group/Events/GroupChangedEvent.php | 94 | ||||
-rw-r--r-- | lib/public/IGroupManager.php | 10 |
8 files changed, 214 insertions, 3 deletions
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index d8016e10b79..90e7fe51fa7 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -402,6 +402,7 @@ return array( 'OCP\\Group\\Events\\BeforeGroupDeletedEvent' => $baseDir . '/lib/public/Group/Events/BeforeGroupDeletedEvent.php', 'OCP\\Group\\Events\\BeforeUserAddedEvent' => $baseDir . '/lib/public/Group/Events/BeforeUserAddedEvent.php', 'OCP\\Group\\Events\\BeforeUserRemovedEvent' => $baseDir . '/lib/public/Group/Events/BeforeUserRemovedEvent.php', + 'OCP\\Group\\Events\\GroupChangedEvent' => $baseDir . '/lib/public/Group/Events/GroupChangedEvent.php', 'OCP\\Group\\Events\\GroupCreatedEvent' => $baseDir . '/lib/public/Group/Events/GroupCreatedEvent.php', 'OCP\\Group\\Events\\GroupDeletedEvent' => $baseDir . '/lib/public/Group/Events/GroupDeletedEvent.php', 'OCP\\Group\\Events\\SubAdminAddedEvent' => $baseDir . '/lib/public/Group/Events/SubAdminAddedEvent.php', @@ -1280,6 +1281,7 @@ return array( 'OC\\GlobalScale\\Config' => $baseDir . '/lib/private/GlobalScale/Config.php', 'OC\\Group\\Backend' => $baseDir . '/lib/private/Group/Backend.php', 'OC\\Group\\Database' => $baseDir . '/lib/private/Group/Database.php', + 'OC\\Group\\DisplayNameCache' => $baseDir . '/lib/private/Group/DisplayNameCache.php', 'OC\\Group\\Group' => $baseDir . '/lib/private/Group/Group.php', 'OC\\Group\\Manager' => $baseDir . '/lib/private/Group/Manager.php', 'OC\\Group\\MetaData' => $baseDir . '/lib/private/Group/MetaData.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 595c7ec3736..8cef29efc39 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -435,6 +435,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OCP\\Group\\Events\\BeforeGroupDeletedEvent' => __DIR__ . '/../../..' . '/lib/public/Group/Events/BeforeGroupDeletedEvent.php', 'OCP\\Group\\Events\\BeforeUserAddedEvent' => __DIR__ . '/../../..' . '/lib/public/Group/Events/BeforeUserAddedEvent.php', 'OCP\\Group\\Events\\BeforeUserRemovedEvent' => __DIR__ . '/../../..' . '/lib/public/Group/Events/BeforeUserRemovedEvent.php', + 'OCP\\Group\\Events\\GroupChangedEvent' => __DIR__ . '/../../..' . '/lib/public/Group/Events/GroupChangedEvent.php', 'OCP\\Group\\Events\\GroupCreatedEvent' => __DIR__ . '/../../..' . '/lib/public/Group/Events/GroupCreatedEvent.php', 'OCP\\Group\\Events\\GroupDeletedEvent' => __DIR__ . '/../../..' . '/lib/public/Group/Events/GroupDeletedEvent.php', 'OCP\\Group\\Events\\SubAdminAddedEvent' => __DIR__ . '/../../..' . '/lib/public/Group/Events/SubAdminAddedEvent.php', @@ -1313,6 +1314,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OC\\GlobalScale\\Config' => __DIR__ . '/../../..' . '/lib/private/GlobalScale/Config.php', 'OC\\Group\\Backend' => __DIR__ . '/../../..' . '/lib/private/Group/Backend.php', 'OC\\Group\\Database' => __DIR__ . '/../../..' . '/lib/private/Group/Database.php', + 'OC\\Group\\DisplayNameCache' => __DIR__ . '/../../..' . '/lib/private/Group/DisplayNameCache.php', 'OC\\Group\\Group' => __DIR__ . '/../../..' . '/lib/private/Group/Group.php', 'OC\\Group\\Manager' => __DIR__ . '/../../..' . '/lib/private/Group/Manager.php', 'OC\\Group\\MetaData' => __DIR__ . '/../../..' . '/lib/private/Group/MetaData.php', diff --git a/lib/private/Group/DisplayNameCache.php b/lib/private/Group/DisplayNameCache.php new file mode 100644 index 00000000000..d724b6caf0e --- /dev/null +++ b/lib/private/Group/DisplayNameCache.php @@ -0,0 +1,87 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright 2022 Anna Larch <anna.larch@gmx.net> + * @author Anna Larch <anna.larch@gmx.net> + * + * @license AGPL-3.0-or-later + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + + +namespace OC\Group; + +use OCP\Cache\CappedMemoryCache; +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; +use OCP\Group\Events\GroupChangedEvent; +use OCP\ICache; +use OCP\ICacheFactory; +use OCP\IGroupManager; + +/** + * Class that cache the relation Group ID -> Display name + * + * This saves fetching the group from the backend for "just" the display name + */ +class DisplayNameCache implements IEventListener { + private CappedMemoryCache $cache; + private ICache $memCache; + private IGroupManager $groupManager; + + public function __construct(ICacheFactory $cacheFactory, IGroupManager $groupManager) { + $this->cache = new CappedMemoryCache(); + $this->memCache = $cacheFactory->createDistributed('groupDisplayNameMappingCache'); + $this->groupManager = $groupManager; + } + + public function getDisplayName(string $groupId): ?string { + if (isset($this->cache[$groupId])) { + return $this->cache[$groupId]; + } + $displayName = $this->memCache->get($groupId); + if ($displayName) { + $this->cache[$groupId] = $displayName; + return $displayName; + } + + $group = $this->groupManager->get($groupId); + if ($group) { + $displayName = $group->getDisplayName(); + } else { + $displayName = null; + } + $this->cache[$groupId] = $displayName; + $this->memCache->set($groupId, $displayName, 60 * 10); // 10 minutes + + return $displayName; + } + + public function clear(): void { + $this->cache = new CappedMemoryCache(); + $this->memCache->clear(); + } + + public function handle(Event $event): void { + if ($event instanceof GroupChangedEvent && $event->getFeature() === 'displayName') { + $groupId = $event->getGroup()->getGID(); + $newDisplayName = $event->getValue(); + $this->cache[$groupId] = $newDisplayName; + $this->memCache->set($groupId, $newDisplayName, 60 * 10); // 10 minutes + } + } +} diff --git a/lib/private/Group/Group.php b/lib/private/Group/Group.php index 2ef4d2ee23f..ae70a611e4e 100644 --- a/lib/private/Group/Group.php +++ b/lib/private/Group/Group.php @@ -38,6 +38,7 @@ use OCP\Group\Backend\IGetDisplayNameBackend; use OCP\Group\Backend\IHideFromCollaborationBackend; use OCP\Group\Backend\INamedBackend; use OCP\Group\Backend\ISetDisplayNameBackend; +use OCP\Group\Events\GroupChangedEvent; use OCP\GroupInterface; use OCP\IGroup; use OCP\IUser; @@ -112,6 +113,7 @@ class Group implements IGroup { if (($backend instanceof ISetDisplayNameBackend) && $backend->setDisplayName($this->gid, $displayName)) { $this->displayName = $displayName; + $this->dispatcher->dispatch(new GroupChangedEvent($this, 'displayName', $displayName, '')); return true; } } diff --git a/lib/private/Group/Manager.php b/lib/private/Group/Manager.php index 28f7a400b41..b718afa5168 100644 --- a/lib/private/Group/Manager.php +++ b/lib/private/Group/Manager.php @@ -42,6 +42,7 @@ namespace OC\Group; use OC\Hooks\PublicEmitter; use OCP\EventDispatcher\IEventDispatcher; use OCP\GroupInterface; +use OCP\ICacheFactory; use OCP\IGroup; use OCP\IGroupManager; use OCP\IUser; @@ -82,12 +83,16 @@ class Manager extends PublicEmitter implements IGroupManager { /** @var \OC\SubAdmin */ private $subAdmin = null; + private DisplayNameCache $displayNameCache; + public function __construct(\OC\User\Manager $userManager, EventDispatcherInterface $dispatcher, - LoggerInterface $logger) { + LoggerInterface $logger, + ICacheFactory $cacheFactory) { $this->userManager = $userManager; $this->dispatcher = $dispatcher; $this->logger = $logger; + $this->displayNameCache = new DisplayNameCache($cacheFactory, $this); $cachedGroups = &$this->cachedGroups; $cachedUserGroups = &$this->cachedUserGroups; @@ -339,6 +344,14 @@ class Manager extends PublicEmitter implements IGroupManager { } /** + * @param string $groupId + * @return ?string + */ + public function getDisplayName(string $groupId): ?string { + return $this->displayNameCache->getDisplayName($groupId); + } + + /** * get an array of groupid and displayName for a user * * @param IUser $user @@ -346,7 +359,7 @@ class Manager extends PublicEmitter implements IGroupManager { */ public function getUserGroupNames(IUser $user) { return array_map(function ($group) { - return ['displayName' => $group->getDisplayName()]; + return ['displayName' => $this->displayNameCache->getDisplayName($group->getGID())]; }, $this->getUserGroups($user)); } diff --git a/lib/private/Server.php b/lib/private/Server.php index 39bfc08dafd..07e90843a98 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -487,7 +487,8 @@ class Server extends ServerContainer implements IServerContainer { $groupManager = new \OC\Group\Manager( $this->get(IUserManager::class), $c->get(SymfonyAdapter::class), - $this->get(LoggerInterface::class) + $this->get(LoggerInterface::class), + $this->get(ICacheFactory::class) ); $groupManager->listen('\OC\Group', 'preCreate', function ($gid) { /** @var IEventDispatcher $dispatcher */ diff --git a/lib/public/Group/Events/GroupChangedEvent.php b/lib/public/Group/Events/GroupChangedEvent.php new file mode 100644 index 00000000000..9cb5007a916 --- /dev/null +++ b/lib/public/Group/Events/GroupChangedEvent.php @@ -0,0 +1,94 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright 2022 Anna Larch <anna.larch@gmx.net> + * + * @author Anna Larch <anna.larch@gmx.net> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ +namespace OCP\Group\Events; + +use OCP\EventDispatcher\Event; +use OCP\IGroup; + +/** + * @since 26.0.0 + */ +class GroupChangedEvent extends Event { + private IGroup $group; + private string $feature; + /** @var mixed */ + private $value; + /** @var mixed */ + private $oldValue; + + /** + * @since 26.0.0 + */ + public function __construct(IGroup $group, + string $feature, + $value, + $oldValue = null) { + parent::__construct(); + $this->group = $group; + $this->feature = $feature; + $this->value = $value; + $this->oldValue = $oldValue; + } + + /** + * + * @since 26.0.0 + * + * @return IGroup + */ + public function getGroup(): IGroup { + return $this->group; + } + + /** + * + * @since 26.0.0 + * + * @return string + */ + public function getFeature(): string { + return $this->feature; + } + + /** + * @since 26.0.0 + * + * @return mixed + */ + public function getValue() { + return $this->value; + } + + /** + * + * @since 26.0.0 + * + * @return mixed + */ + public function getOldValue() { + return $this->oldValue; + } +} diff --git a/lib/public/IGroupManager.php b/lib/public/IGroupManager.php index d942caac9b4..2e2685eeeb4 100644 --- a/lib/public/IGroupManager.php +++ b/lib/public/IGroupManager.php @@ -145,4 +145,14 @@ interface IGroupManager { * @since 8.0.0 */ public function isInGroup($userId, $group); + + /** + * Get the display name of a Nextcloud group + * + * @param string $groupId + * @return ?string display name, if any + * + * @since 26.0.0 + */ + public function getDisplayName(string $groupId): ?string; } |