diff --git a/lib/private/TaskProcessing/Manager.php b/lib/private/TaskProcessing/Manager.php index b546c1e75ade4..84bfbcca190c9 100644 --- a/lib/private/TaskProcessing/Manager.php +++ b/lib/private/TaskProcessing/Manager.php @@ -31,6 +31,8 @@ use OCP\Files\NotPermittedException; use OCP\Files\SimpleFS\ISimpleFile; use OCP\Http\Client\IClientService; +use OCP\ICache; +use OCP\ICacheFactory; use OCP\IConfig; use OCP\IL10N; use OCP\IServerContainer; @@ -77,6 +79,11 @@ class Manager implements IManager { private ?array $availableTaskTypes = null; private IAppData $appData; + private ?array $preferences = null; + private ?array $providersById = null; + private ICache $cache; + private ICache $distributedCache; + public function __construct( private IConfig $config, private Coordinator $coordinator, @@ -91,8 +98,11 @@ public function __construct( private IUserMountCache $userMountCache, private IClientService $clientService, private IAppManager $appManager, + ICacheFactory $cacheFactory, ) { $this->appData = $appDataFactory->get('core'); + $this->cache = $cacheFactory->createLocal('task_processing::'); + $this->distributedCache = $cacheFactory->createDistributed('task_processing::'); } @@ -698,12 +708,23 @@ public function getProviders(): array { public function getPreferredProvider(string $taskTypeId) { try { - $preferences = json_decode($this->config->getAppValue('core', 'ai.taskprocessing_provider_preferences', 'null'), associative: true, flags: JSON_THROW_ON_ERROR); + if ($this->preferences === null) { + $this->preferences = $this->distributedCache->get('ai.taskprocessing_provider_preferences'); + if ($this->preferences === null) { + $this->preferences = json_decode($this->config->getAppValue('core', 'ai.taskprocessing_provider_preferences', 'null'), associative: true, flags: JSON_THROW_ON_ERROR); + $this->distributedCache->set('ai.taskprocessing_provider_preferences', $this->preferences, 60 * 3); + } + } + $providers = $this->getProviders(); - if (isset($preferences[$taskTypeId])) { - $provider = current(array_values(array_filter($providers, fn ($provider) => $provider->getId() === $preferences[$taskTypeId]))); - if ($provider !== false) { - return $provider; + if (isset($this->preferences[$taskTypeId])) { + $providersById = $this->providersById ?? array_reduce($providers, static function (array $carry, IProvider $provider) { + $carry[$provider->getId()] = $provider; + return $carry; + }, []); + $this->providersById = $providersById; + if (isset($providersById[$this->preferences[$taskTypeId]])) { + return $providersById[$this->preferences[$taskTypeId]]; } } // By default, use the first available provider @@ -719,6 +740,10 @@ public function getPreferredProvider(string $taskTypeId) { } public function getAvailableTaskTypes(): array { + if ($this->availableTaskTypes === null) { + // We use local cache only because distributed cache uses JSOn stringify which would botch our ShapeDescriptor objects + $this->availableTaskTypes = $this->cache->get('available_task_types'); + } if ($this->availableTaskTypes === null) { $taskTypes = $this->_getTaskTypes(); @@ -750,6 +775,7 @@ public function getAvailableTaskTypes(): array { } $this->availableTaskTypes = $availableTaskTypes; + $this->cache->set('available_task_types', $this->availableTaskTypes, 60); } return $this->availableTaskTypes; diff --git a/tests/lib/TaskProcessing/TaskProcessingTest.php b/tests/lib/TaskProcessing/TaskProcessingTest.php index 0fb281a0533b6..91baa56247624 100644 --- a/tests/lib/TaskProcessing/TaskProcessingTest.php +++ b/tests/lib/TaskProcessing/TaskProcessingTest.php @@ -21,6 +21,7 @@ use OCP\Files\Config\IUserMountCache; use OCP\Files\IRootFolder; use OCP\Http\Client\IClientService; +use OCP\ICacheFactory; use OCP\IConfig; use OCP\IDBConnection; use OCP\IServerContainer; @@ -475,6 +476,7 @@ protected function setUp(): void { $this->userMountCache, \OC::$server->get(IClientService::class), \OC::$server->get(IAppManager::class), + \OC::$server->get(ICacheFactory::class), ); }