From 25496e53c5b0a66ad485a6671e0f8b698748309f Mon Sep 17 00:00:00 2001 From: Anupam Kumar Date: Fri, 14 Nov 2025 18:17:30 +0530 Subject: [PATCH 1/6] feat: use lazy app config values and small fixes - use `isEnabledForAnyone` instead of `isInstalled` to check for app_api - type annotations for both OCP and the OCA IContentProvider - make `indexed_files_count` app config non-lazy Signed-off-by: Anupam Kumar --- lib/AppInfo/Application.php | 6 ------ lib/BackgroundJobs/ActionJob.php | 10 ++++------ lib/BackgroundJobs/FileSystemListenerJob.php | 8 ++++---- lib/BackgroundJobs/IndexerJob.php | 16 ++++++++-------- lib/BackgroundJobs/InitialContentImportJob.php | 10 ++++++---- lib/BackgroundJobs/RotateLogsJob.php | 6 ++++-- lib/BackgroundJobs/SchedulerJob.php | 5 +++-- lib/BackgroundJobs/StorageCrawlJob.php | 7 +++---- lib/BackgroundJobs/SubmitContentJob.php | 4 ++-- lib/Command/Statistics.php | 8 ++++---- lib/Controller/ConfigController.php | 13 +++++++------ lib/Listener/ShareListener.php | 3 --- lib/Logger.php | 7 ++++--- .../Version004000000Date20241217110041.php | 7 +++---- .../Version4000Date20241108004215.php | 7 ++++--- lib/Public/ContentManager.php | 12 ++++++------ lib/Repair/AppInstallStep.php | 12 ++++-------- lib/Service/DiagnosticService.php | 5 ++++- lib/Service/LangRopeService.php | 14 +++++++------- lib/Service/ProviderConfigService.php | 18 +++++++++--------- lib/Service/ScanService.php | 2 +- lib/Settings/AdminSettings.php | 10 ++++++---- lib/TaskProcessing/ContextChatProvider.php | 2 +- 23 files changed, 94 insertions(+), 98 deletions(-) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index da585b91..47197838 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -28,7 +28,6 @@ use OCP\Files\Events\Node\NodeRenamedEvent; use OCP\Files\Events\Node\NodeWrittenEvent; use OCP\Files\Events\NodeRemovedFromCache; -use OCP\IConfig; use OCP\Share\Events\ShareCreatedEvent; use OCP\Share\Events\ShareDeletedEvent; use OCP\User\Events\UserDeletedEvent; @@ -64,13 +63,8 @@ class Application extends App implements IBootstrap { 'text/org', ]; - private IConfig $config; - public function __construct(array $urlParams = []) { parent::__construct(self::APP_ID, $urlParams); - - $container = $this->getContainer(); - $this->config = $container->get(IConfig::class); } public function register(IRegistrationContext $context): void { diff --git a/lib/BackgroundJobs/ActionJob.php b/lib/BackgroundJobs/ActionJob.php index 06685e9e..91ed6f9d 100644 --- a/lib/BackgroundJobs/ActionJob.php +++ b/lib/BackgroundJobs/ActionJob.php @@ -15,11 +15,10 @@ use OCA\ContextChat\Service\LangRopeService; use OCA\ContextChat\Type\ActionType; use OCP\App\IAppManager; +use OCP\AppFramework\Services\IAppConfig; use OCP\AppFramework\Utility\ITimeFactory; -use OCP\BackgroundJob\IJobList; use OCP\BackgroundJob\TimedJob; use OCP\DB\Exception; -use OCP\IConfig; class ActionJob extends TimedJob { private const BATCH_SIZE = 1000; @@ -28,11 +27,10 @@ public function __construct( ITimeFactory $timeFactory, private LangRopeService $networkService, private QueueActionMapper $actionMapper, - private IJobList $jobList, private Logger $logger, private DiagnosticService $diagnosticService, private IAppManager $appManager, - private IConfig $config, + private IAppConfig $appConfig, ) { parent::__construct($timeFactory); $this->setAllowParallelRuns(false); @@ -40,11 +38,11 @@ public function __construct( } private function getJobInterval(): int { - return intval($this->config->getAppValue('context_chat', 'action_job_interval', (string)(5 * 60))); // 5 minutes + return intval($this->appConfig->getAppValueString('action_job_interval', (string)(5 * 60), true)); // 5 minutes } protected function run($argument): void { - if (!$this->appManager->isInstalled('app_api')) { + if (!$this->appManager->isEnabledForAnyone('app_api')) { $this->logger->warning('ActionJob is skipped as app_api is disabled'); return; } diff --git a/lib/BackgroundJobs/FileSystemListenerJob.php b/lib/BackgroundJobs/FileSystemListenerJob.php index 999cb8cf..842c7ae3 100644 --- a/lib/BackgroundJobs/FileSystemListenerJob.php +++ b/lib/BackgroundJobs/FileSystemListenerJob.php @@ -16,11 +16,11 @@ use OCA\ContextChat\Service\FsEventService; use OCA\ContextChat\Type\FsEventType; use OCP\App\IAppManager; +use OCP\AppFramework\Services\IAppConfig; use OCP\AppFramework\Utility\ITimeFactory; use OCP\BackgroundJob\TimedJob; use OCP\DB\Exception; use OCP\Files\IRootFolder; -use OCP\IConfig; class FileSystemListenerJob extends TimedJob { private const BATCH_SIZE = 500; @@ -40,7 +40,7 @@ public function __construct( private IAppManager $appManager, private FsEventService $fsEventService, private IRootFolder $rootFolder, - private IConfig $config, + private IAppConfig $appConfig, ) { parent::__construct($timeFactory); $this->allowParallelRuns = false; @@ -48,11 +48,11 @@ public function __construct( } private function getJobInterval(): int { - return intval($this->config->getAppValue('context_chat', 'fs_listener_job_interval', (string)(5 * 60))); // 5 minutes + return intval($this->appConfig->getAppValueString('fs_listener_job_interval', (string)(5 * 60), true)); // 5 minutes } protected function run($argument): void { - if (!$this->appManager->isInstalled('app_api')) { + if (!$this->appManager->isEnabledForAnyone('app_api')) { $this->logger->warning('FileSystemListenerJob is skipped as app_api is disabled'); return; } diff --git a/lib/BackgroundJobs/IndexerJob.php b/lib/BackgroundJobs/IndexerJob.php index 58a24a53..ec063dde 100644 --- a/lib/BackgroundJobs/IndexerJob.php +++ b/lib/BackgroundJobs/IndexerJob.php @@ -84,14 +84,14 @@ public function __construct( * @throws \Throwable */ public function run($argument): void { - if (!$this->appManager->isInstalled('app_api')) { + if (!$this->appManager->isEnabledForAnyone('app_api')) { $this->logger->warning('IndexerJob is skipped as app_api is disabled'); return; } $this->storageId = $argument['storageId']; $this->rootId = $argument['rootId']; - if ($this->appConfig->getAppValue('auto_indexing', 'true') === 'false') { + if ($this->appConfig->getAppValueString('auto_indexing', 'true', true) === 'false') { return; } $this->diagnosticService->sendJobTrigger(static::class, $this->getId()); @@ -149,19 +149,19 @@ public function run($argument): void { } protected function getBatchSize(): int { - return $this->appConfig->getAppValueInt('indexing_batch_size', self::DEFAULT_BATCH_SIZE); + return $this->appConfig->getAppValueInt('indexing_batch_size', self::DEFAULT_BATCH_SIZE, true); } protected function getMaxIndexingTime(): int { - return $this->appConfig->getAppValueInt('indexing_max_time', self::DEFAULT_MAX_INDEXING_TIME); + return $this->appConfig->getAppValueInt('indexing_max_time', self::DEFAULT_MAX_INDEXING_TIME, true); } protected function getJobInterval(): int { - return $this->appConfig->getAppValueInt('indexing_job_interval', self::DEFAULT_JOB_INTERVAL); + return $this->appConfig->getAppValueInt('indexing_job_interval', self::DEFAULT_JOB_INTERVAL, true); } protected function getMaxSize(): float { - return (float)$this->appConfig->getAppValueInt('indexing_max_size', Application::CC_MAX_SIZE); + return (float)$this->appConfig->getAppValueInt('indexing_max_size', Application::CC_MAX_SIZE, true); } /** @@ -321,7 +321,7 @@ protected function index(array $files): void { } private function setInitialIndexCompletion(): void { - if ($this->appConfig->getAppValueInt('last_indexed_time', 0) !== 0) { + if ($this->appConfig->getAppValueInt('last_indexed_time', 0, true) !== 0) { return; } try { @@ -345,7 +345,7 @@ private function setInitialIndexCompletion(): void { } $this->logger->info('Initial index completion detected, setting last indexed time'); - $this->appConfig->setAppValueInt('last_indexed_time', $this->timeFactory->getTime(), false); + $this->appConfig->setAppValueInt('last_indexed_time', $this->timeFactory->getTime(), true); } /** diff --git a/lib/BackgroundJobs/InitialContentImportJob.php b/lib/BackgroundJobs/InitialContentImportJob.php index c08ec5d4..dbf68163 100644 --- a/lib/BackgroundJobs/InitialContentImportJob.php +++ b/lib/BackgroundJobs/InitialContentImportJob.php @@ -10,11 +10,12 @@ namespace OCA\ContextChat\BackgroundJobs; use OCA\ContextChat\Logger; -use OCA\ContextChat\Public\IContentProvider; +use OCA\ContextChat\Public\IContentProvider as OCAIContentProvider; use OCA\ContextChat\Service\ProviderConfigService; use OCP\App\IAppManager; use OCP\AppFramework\Utility\ITimeFactory; use OCP\BackgroundJob\QueuedJob; +use OCP\ContextChat\IContentProvider as OCPIContentProvider; use OCP\IUserManager; use OCP\Server; use Psr\Container\ContainerExceptionInterface; @@ -33,7 +34,7 @@ public function __construct( } /** - * @param class-string $argument Provider class name + * @param class-string $argument Provider class name * @return void */ protected function run($argument): void { @@ -42,14 +43,15 @@ protected function run($argument): void { } try { - /** @var IContentProvider */ + /** @var OCAIContentProvider|OCPIContentProvider */ $providerObj = Server::get($argument); } catch (ContainerExceptionInterface|NotFoundExceptionInterface $e) { $this->logger->warning('[InitialContentImportJob] Could not run initial import for content provider', ['exception' => $e]); return; } - if (!$this->appManager->isEnabledForUser($providerObj->getAppId())) { + $user = $this->userMan->get($this->userId ?? ''); + if (!$this->appManager->isEnabledForUser($providerObj->getAppId(), $user)) { $this->logger->info('[InitialContentImportJob] App is not enabled for user, skipping content import', ['appId' => $providerObj->getAppId()]); return; } diff --git a/lib/BackgroundJobs/RotateLogsJob.php b/lib/BackgroundJobs/RotateLogsJob.php index e5b79283..51c729fe 100755 --- a/lib/BackgroundJobs/RotateLogsJob.php +++ b/lib/BackgroundJobs/RotateLogsJob.php @@ -7,6 +7,7 @@ */ namespace OCA\ContextChat\BackgroundJobs; +use OCP\AppFramework\Services\IAppConfig; use OCP\AppFramework\Utility\ITimeFactory; use OCP\BackgroundJob\TimedJob; use OCP\IConfig; @@ -18,15 +19,16 @@ class RotateLogsJob extends TimedJob { public function __construct( ITimeFactory $time, private IConfig $config, + private IAppConfig $appConfig, ) { parent::__construct($time); - $this->setInterval(60 * 60 * 3); + $this->setInterval(60 * 60 * 3); // every 3 hours } protected function run($argument): void { $default = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/context_chat.log'; - $this->filePath = $this->config->getAppValue('context_chat', 'logfile', $default); + $this->filePath = $this->appConfig->getAppValueString('logfile', $default, true); $this->maxSize = $this->config->getSystemValue('log_rotate_size', 100 * 1024 * 1024); diff --git a/lib/BackgroundJobs/SchedulerJob.php b/lib/BackgroundJobs/SchedulerJob.php index 380a1e8b..66466486 100644 --- a/lib/BackgroundJobs/SchedulerJob.php +++ b/lib/BackgroundJobs/SchedulerJob.php @@ -34,8 +34,9 @@ public function __construct( * @throws Exception */ protected function run($argument): void { - $this->appConfig->setAppValueString('indexed_files_count', (string)0); - $this->appConfig->setAppValueInt('last_indexed_time', 0); + // todo: non-lazy since this needs to change often in one process, like in the diagnostics service + $this->appConfig->setAppValueString('indexed_files_count', (string)0, false); + $this->appConfig->setAppValueInt('last_indexed_time', 0, true); foreach ($this->storageService->getMounts() as $mount) { $this->logger->debug('Scheduling StorageCrawlJob storage_id=' . $mount['storage_id'] . ' root_id=' . $mount['root_id' ] . 'override_root=' . $mount['overridden_root']); $this->jobList->add(StorageCrawlJob::class, [ diff --git a/lib/BackgroundJobs/StorageCrawlJob.php b/lib/BackgroundJobs/StorageCrawlJob.php index 9da33094..134f33ec 100644 --- a/lib/BackgroundJobs/StorageCrawlJob.php +++ b/lib/BackgroundJobs/StorageCrawlJob.php @@ -10,17 +10,16 @@ namespace OCA\ContextChat\BackgroundJobs; -use OCA\ContextChat\AppInfo\Application; use OCA\ContextChat\Db\QueueFile; use OCA\ContextChat\Logger; use OCA\ContextChat\Service\DiagnosticService; use OCA\ContextChat\Service\QueueService; use OCA\ContextChat\Service\StorageService; +use OCP\AppFramework\Services\IAppConfig; use OCP\AppFramework\Utility\ITimeFactory; use OCP\BackgroundJob\IJobList; use OCP\BackgroundJob\QueuedJob; use OCP\DB\Exception; -use OCP\IAppConfig; class StorageCrawlJob extends QueuedJob { public const BATCH_SIZE = 2000; @@ -91,7 +90,7 @@ protected function run($argument): void { if ($lastSuccessfulFileId !== -1) { // the last job to set this value will win - $this->appConfig->setValueInt(Application::APP_ID, 'last_indexed_file_id', $lastSuccessfulFileId); + $this->appConfig->setAppValueInt('last_indexed_file_id', $lastSuccessfulFileId, true); } } } finally { @@ -100,6 +99,6 @@ protected function run($argument): void { } protected function getJobInterval(): int { - return $this->appConfig->getValueInt(Application::APP_ID, 'crawl_job_interval', self::DEFAULT_JOB_INTERVAL); + return $this->appConfig->getAppValueInt('crawl_job_interval', self::DEFAULT_JOB_INTERVAL, true); } } diff --git a/lib/BackgroundJobs/SubmitContentJob.php b/lib/BackgroundJobs/SubmitContentJob.php index 7f0570f6..1975e18c 100644 --- a/lib/BackgroundJobs/SubmitContentJob.php +++ b/lib/BackgroundJobs/SubmitContentJob.php @@ -46,7 +46,7 @@ public function __construct( * @return void */ protected function run($argument): void { - if (!$this->appManager->isInstalled('app_api')) { + if (!$this->appManager->isEnabledForAnyone('app_api')) { $this->logger->warning('SubmitContentJob is skipped as app_api is disabled'); return; } @@ -63,7 +63,7 @@ protected function run($argument): void { return; } - $maxSize = $this->appConfig->getAppValueInt('indexing_max_size', Application::CC_MAX_SIZE); + $maxSize = $this->appConfig->getAppValueInt('indexing_max_size', Application::CC_MAX_SIZE, true); if (empty($entities)) { return; diff --git a/lib/Command/Statistics.php b/lib/Command/Statistics.php index 31a2c7c4..e0868e47 100644 --- a/lib/Command/Statistics.php +++ b/lib/Command/Statistics.php @@ -42,11 +42,11 @@ protected function configure() { protected function execute(InputInterface $input, OutputInterface $output): int { $output->writeln('ContextChat statistics:'); - if ($this->appConfig->getAppValueInt('last_indexed_time', 0) === 0) { + if ($this->appConfig->getAppValueInt('last_indexed_time', 0, true) === 0) { $output->writeln('The indexing is not complete yet.'); } else { - $installedTime = $this->appConfig->getAppValueInt('installed_time', 0); - $lastIndexedTime = $this->appConfig->getAppValueInt('last_indexed_time', 0); + $installedTime = $this->appConfig->getAppValueInt('installed_time', 0, true); + $lastIndexedTime = $this->appConfig->getAppValueInt('last_indexed_time', 0, true); $indexTime = $lastIndexedTime - $installedTime; $output->writeln('Installed time: ' . (new \DateTime('@' . $installedTime))->format('Y-m-d H:i') . ' UTC'); @@ -66,7 +66,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $queuedDocumentsCount = $this->contentQueue->count(); $output->writeln('Queued documents (without files):' . var_export($queuedDocumentsCount, true)); - $indexFilesCount = Util::numericToNumber($this->appConfig->getAppValueString('indexed_files_count', '0')); + $indexFilesCount = Util::numericToNumber(intval($this->appConfig->getAppValueString('indexed_files_count', '0', false))); $output->writeln('Files successfully sent to backend: ' . strval($indexFilesCount)); $indexedDocumentsCount = $this->langRopeService->getIndexedDocumentsCounts(); diff --git a/lib/Controller/ConfigController.php b/lib/Controller/ConfigController.php index b30a1d14..e1ee7d4b 100644 --- a/lib/Controller/ConfigController.php +++ b/lib/Controller/ConfigController.php @@ -7,12 +7,10 @@ namespace OCA\ContextChat\Controller; -use OCA\ContextChat\AppInfo\Application; use OCP\AppFramework\Controller; use OCP\AppFramework\Http\Attribute\NoAdminRequired; use OCP\AppFramework\Http\DataResponse; -use OCP\IConfig; - +use OCP\AppFramework\Services\IAppConfig; use OCP\IRequest; use OCP\PreConditionNotMetException; @@ -21,7 +19,7 @@ class ConfigController extends Controller { public function __construct( string $appName, IRequest $request, - private IConfig $config, + private IAppConfig $appConfig, private ?string $userId, ) { parent::__construct($appName, $request); @@ -36,8 +34,11 @@ public function __construct( */ #[NoAdminRequired] public function setConfig(array $values): DataResponse { + if ($this->userId === null) { + throw new PreConditionNotMetException('User must be logged in to set user config values'); + } foreach ($values as $key => $value) { - $this->config->setUserValue($this->userId, Application::APP_ID, $key, $value); + $this->appConfig->setUserValue($this->userId, $key, $value); } return new DataResponse(1); } @@ -50,7 +51,7 @@ public function setConfig(array $values): DataResponse { */ public function setAdminConfig(array $values): DataResponse { foreach ($values as $key => $value) { - $this->config->setAppValue(Application::APP_ID, $key, $value); + $this->appConfig->setAppValueString($key, $value, true); } return new DataResponse(1); } diff --git a/lib/Listener/ShareListener.php b/lib/Listener/ShareListener.php index fe16be67..528bd4f1 100644 --- a/lib/Listener/ShareListener.php +++ b/lib/Listener/ShareListener.php @@ -18,10 +18,8 @@ use OCA\ContextChat\Service\StorageService; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; -use OCP\Files\File; use OCP\Files\FileInfo; use OCP\Files\Folder; -use OCP\Files\IRootFolder; use OCP\Files\Node; use OCP\IGroupManager; use OCP\Share\Events\ShareCreatedEvent; @@ -37,7 +35,6 @@ public function __construct( private Logger $logger, private StorageService $storageService, private IManager $shareManager, - private IRootFolder $rootFolder, private ActionScheduler $actionService, private IGroupManager $groupManager, ) { diff --git a/lib/Logger.php b/lib/Logger.php index 9bc8a476..fce909fc 100644 --- a/lib/Logger.php +++ b/lib/Logger.php @@ -9,7 +9,7 @@ namespace OCA\ContextChat; -use OCA\ContextChat\AppInfo\Application; +use OCP\AppFramework\Services\IAppConfig; use OCP\IConfig; use OCP\Log\ILogFactory; use Psr\Log\LoggerInterface; @@ -26,6 +26,7 @@ class Logger { public function __construct( ILogFactory $logFactory, private IConfig $config, + private IAppConfig $appConfig, ) { $logFilepath = $this->getLogFilepath(); $this->parentLogger = $logFactory->getCustomPsrLogger($logFilepath, 'file', 'Nextcloud Context Chat'); @@ -33,8 +34,8 @@ public function __construct( public function getLogFilepath(): string { $default = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/context_chat.log'; - // Legacy way was appconfig, now it's paralleled with the normal log config - return $this->config->getAppValue(Application::APP_ID, 'logfile', $default); + // todo: Legacy way was appconfig, now it's paralleled with the normal log config (?) + return $this->appConfig->getAppValueString('logfile', $default, true); } public function emergency(Stringable|string $message, array $context = []): void { diff --git a/lib/Migration/Version004000000Date20241217110041.php b/lib/Migration/Version004000000Date20241217110041.php index ce9e5653..b964b4f3 100644 --- a/lib/Migration/Version004000000Date20241217110041.php +++ b/lib/Migration/Version004000000Date20241217110041.php @@ -10,16 +10,15 @@ namespace OCA\ContextChat\Migration; use Closure; -use OCA\ContextChat\AppInfo\Application; use OCA\ContextChat\BackgroundJobs\IndexerJob; use OCA\ContextChat\BackgroundJobs\InitialContentImportJob; use OCA\ContextChat\BackgroundJobs\SchedulerJob; use OCA\ContextChat\BackgroundJobs\StorageCrawlJob; use OCA\ContextChat\BackgroundJobs\SubmitContentJob; +use OCP\AppFramework\Services\IAppConfig; use OCP\BackgroundJob\IJobList; use OCP\DB\Exception; use OCP\DB\ISchemaWrapper; -use OCP\IConfig; use OCP\IDBConnection; use OCP\Migration\IOutput; use OCP\Migration\SimpleMigrationStep; @@ -29,7 +28,7 @@ class Version004000000Date20241217110041 extends SimpleMigrationStep { public function __construct( private IDBConnection $db, private IJobList $jobList, - private IConfig $config, + private IAppConfig $appConfig, ) { } @@ -96,7 +95,7 @@ public function postSchemaChange(IOutput $output, Closure $schemaClosure, array } $output->advance(1); - $this->config->setAppValue(Application::APP_ID, 'providers', ''); + $this->appConfig->setAppValueString('providers', '', true); $output->advance(1); $this->jobList->add(SchedulerJob::class); diff --git a/lib/Migration/Version4000Date20241108004215.php b/lib/Migration/Version4000Date20241108004215.php index 994deb25..e240b9e7 100644 --- a/lib/Migration/Version4000Date20241108004215.php +++ b/lib/Migration/Version4000Date20241108004215.php @@ -16,9 +16,9 @@ use OCA\ContextChat\BackgroundJobs\SchedulerJob; use OCA\ContextChat\BackgroundJobs\StorageCrawlJob; use OCA\ContextChat\BackgroundJobs\SubmitContentJob; +use OCP\AppFramework\Services\IAppConfig; use OCP\BackgroundJob\IJobList; use OCP\DB\Exception; -use OCP\IConfig; use OCP\IDBConnection; use OCP\Migration\IOutput; use OCP\Migration\SimpleMigrationStep; @@ -28,7 +28,7 @@ class Version4000Date20241108004215 extends SimpleMigrationStep { public function __construct( private IDBConnection $db, private IJobList $jobList, - private IConfig $config, + private IAppConfig $appConfig, ) { } @@ -77,7 +77,8 @@ public function postSchemaChange(IOutput $output, Closure $schemaClosure, array } $output->advance(1); - $this->config->setAppValue(Application::APP_ID, 'providers', ''); + // todo: maybe migrations also need to use the newer app config service? + $this->appConfig->setAppValueString('providers', '', true); $output->advance(1); $this->jobList->add(SchedulerJob::class); diff --git a/lib/Public/ContentManager.php b/lib/Public/ContentManager.php index 76b53900..e6840f28 100644 --- a/lib/Public/ContentManager.php +++ b/lib/Public/ContentManager.php @@ -7,22 +7,22 @@ namespace OCA\ContextChat\Public; -use OCA\ContextChat\AppInfo\Application; use OCA\ContextChat\BackgroundJobs\InitialContentImportJob; use OCA\ContextChat\BackgroundJobs\SubmitContentJob; use OCA\ContextChat\Db\QueueContentItem; use OCA\ContextChat\Db\QueueContentItemMapper; use OCA\ContextChat\Event\ContentProviderRegisterEvent; use OCA\ContextChat\Logger; +use OCA\ContextChat\Public\IContentProvider as OCAIContentProvider; use OCA\ContextChat\Service\ActionScheduler; use OCA\ContextChat\Service\ProviderConfigService; +use OCP\AppFramework\Services\IAppConfig; use OCP\BackgroundJob\IJobList; use OCP\ContextChat\ContentItem; use OCP\ContextChat\IContentManager; -use OCP\ContextChat\IContentProvider; +use OCP\ContextChat\IContentProvider as OCPIContentProvider; use OCP\DB\Exception; use OCP\EventDispatcher\IEventDispatcher; -use OCP\IConfig; use OCP\Server; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; @@ -30,7 +30,7 @@ class ContentManager implements IContentManager { public function __construct( private IJobList $jobList, - private IConfig $config, + private IAppConfig $appConfig, private ProviderConfigService $providerConfig, private QueueContentItemMapper $mapper, private ActionScheduler $actionService, @@ -46,13 +46,13 @@ public function __construct( * @since 4.6.0 */ public function isContextChatAvailable(): bool { - return $this->config->getAppValue(Application::APP_ID, 'backend_init', 'false') === 'true'; + return $this->appConfig->getAppValueString('backend_init', 'false', true) === 'true'; } /** * @param string $appId * @param string $providerId - * @param class-string $providerClass + * @param class-string $providerClass * @return void * @since 2.2.2 */ diff --git a/lib/Repair/AppInstallStep.php b/lib/Repair/AppInstallStep.php index 81563b6f..d1241df2 100644 --- a/lib/Repair/AppInstallStep.php +++ b/lib/Repair/AppInstallStep.php @@ -9,13 +9,11 @@ namespace OCA\ContextChat\Repair; -use OCA\ContextChat\AppInfo\Application; use OCA\ContextChat\BackgroundJobs\SchedulerJob; use OCA\ContextChat\Logger; use OCA\ContextChat\Service\ProviderConfigService; +use OCP\AppFramework\Services\IAppConfig; use OCP\BackgroundJob\IJobList; -use OCP\IAppConfig; -use OCP\IConfig; use OCP\Migration\IOutput; use OCP\Migration\IRepairStep; @@ -24,7 +22,6 @@ class AppInstallStep implements IRepairStep { public function __construct( private Logger $logger, private IAppConfig $appConfig, - private IConfig $config, private IJobList $jobList, ) { } @@ -37,13 +34,12 @@ public function getName(): string { * @param IOutput $output */ public function run(IOutput $output): void { - if ($this->appConfig->getValueInt(Application::APP_ID, 'installed_time', 0, false) === 0) { + if ($this->appConfig->getAppValueInt('installed_time', 0, true) === 0) { $this->logger->info('Setting up Context Chat for the first time'); - $this->appConfig->setValueInt(Application::APP_ID, 'installed_time', time(), false); + $this->appConfig->setAppValueInt('installed_time', time(), true); } - // todo: migrate to IAppConfig - $providerConfigService = new ProviderConfigService($this->config); + $providerConfigService = new ProviderConfigService($this->appConfig); /** @psalm-suppress ArgumentTypeCoercion, UndefinedClass */ $providerConfigService->updateProvider('files', 'default', '', true); diff --git a/lib/Service/DiagnosticService.php b/lib/Service/DiagnosticService.php index da616f98..48abfb4c 100644 --- a/lib/Service/DiagnosticService.php +++ b/lib/Service/DiagnosticService.php @@ -61,10 +61,13 @@ public function sendHeartbeat(string $class, int $id): void { public function sendIndexedFiles(int $count): void { $this->logger->info('Indexed ' . $count . ' files'); // We use numericToNumber to fall back to float in case int is too small + // non-lazy since this needs to change often in one process $this->appConfig->setAppValueString( 'indexed_files_count', (string)Util::numericToNumber( - floatval($count) + floatval(Util::numericToNumber($this->appConfig->getAppValueString('indexed_files_count', '0', false))) + floatval($count) + floatval(Util::numericToNumber(intval( + $this->appConfig->getAppValueString('indexed_files_count', '0', false) + ))) ), false, ); diff --git a/lib/Service/LangRopeService.php b/lib/Service/LangRopeService.php index c72c75a9..170be3dc 100644 --- a/lib/Service/LangRopeService.php +++ b/lib/Service/LangRopeService.php @@ -13,7 +13,7 @@ use OCA\ContextChat\Public\IContentProvider; use OCA\ContextChat\Type\Source; use OCP\App\IAppManager; -use OCP\IConfig; +use OCP\AppFramework\Services\IAppConfig; use OCP\IL10N; use OCP\IURLGenerator; use OCP\IUserManager; @@ -26,7 +26,7 @@ class LangRopeService { public function __construct( private Logger $logger, private IL10N $l10n, - private IConfig $config, + private IAppConfig $appConfig, private IAppManager $appManager, private IURLGenerator $urlGenerator, private IUserManager $userMan, @@ -66,7 +66,7 @@ private function requestToExApp( } // backend init check - $backendInit = $this->config->getAppValue(Application::APP_ID, 'backend_init', 'false'); + $backendInit = $this->appConfig->getAppValueString('backend_init', 'false', true); if ($backendInit !== 'true') { $enabledResponse = $appApiFunctions->exAppRequest('context_chat_backend', '/enabled', $this->userId, 'GET'); @@ -88,17 +88,17 @@ private function requestToExApp( } if (isset($enabledResponse['enabled']) && $enabledResponse['enabled'] === true) { - $this->config->setAppValue(Application::APP_ID, 'backend_init', 'true'); + $this->appConfig->setAppValueString('backend_init', 'true', true); } else { - $this->config->setAppValue(Application::APP_ID, 'backend_init', 'false'); + $this->appConfig->setAppValueString('backend_init', 'false', true); throw new RuntimeException('Context Chat backend is not ready yet. Please wait a while before trying again.'); } } - $timeout = $this->config->getAppValue( - Application::APP_ID, + $timeout = $this->appConfig->getAppValueString( 'request_timeout', strval(Application::CC_DEFAULT_REQUEST_TIMEOUT), + true, ); $options = [ 'timeout' => $timeout, diff --git a/lib/Service/ProviderConfigService.php b/lib/Service/ProviderConfigService.php index f8758574..503368ad 100644 --- a/lib/Service/ProviderConfigService.php +++ b/lib/Service/ProviderConfigService.php @@ -7,15 +7,15 @@ namespace OCA\ContextChat\Service; -use OCA\ContextChat\AppInfo\Application; -use OCA\ContextChat\Public\IContentProvider; -use OCP\IConfig; +use OCA\ContextChat\Public\IContentProvider as OCAIContentProvider; +use OCP\AppFramework\Services\IAppConfig; +use OCP\ContextChat\IContentProvider as OCPIContentProvider; /* array<[$appId__$providerId], array{ isInitiated: bool, classString: string }> */ class ProviderConfigService { public function __construct( - private IConfig $config, + private IAppConfig $appConfig, ) { } @@ -78,14 +78,14 @@ public function getProvider(string $providerKey): ?array { */ public function getProviders(): array { $providers = []; - $providersString = $this->config->getAppValue(Application::APP_ID, 'providers', ''); + $providersString = $this->appConfig->getAppValueString('providers', '', true); if ($providersString !== '') { $providers = json_decode($providersString, true); if ($providers === null || !$this->validateProvidersArray($providers)) { $providers = []; - $this->config->setAppValue(Application::APP_ID, 'providers', ''); + $this->appConfig->setAppValueString('providers', '', true); } } @@ -95,7 +95,7 @@ public function getProviders(): array { /** * @param string $appId * @param string $providerId - * @param class-string $providerClass + * @param class-string $providerClass * @param bool $isInitiated */ public function updateProvider( @@ -109,7 +109,7 @@ public function updateProvider( 'isInitiated' => $isInitiated, 'classString' => $providerClass, ]; - $this->config->setAppValue(Application::APP_ID, 'providers', json_encode($providers)); + $this->appConfig->setAppValueString('providers', json_encode($providers), true); } /** @@ -129,7 +129,7 @@ public function removeProvider(string $appId, ?string $providerId = null): void } } - $this->config->setAppValue(Application::APP_ID, 'providers', json_encode($providers)); + $this->appConfig->setAppValueString('providers', json_encode($providers), true); } /** diff --git a/lib/Service/ScanService.php b/lib/Service/ScanService.php index 9628859e..c92ab835 100644 --- a/lib/Service/ScanService.php +++ b/lib/Service/ScanService.php @@ -49,7 +49,7 @@ public function scanUserFiles(string $userId, array $mimeTypeFilter, ?string $di * @return \Generator */ public function scanDirectory(array $mimeTypeFilter, Folder $directory): \Generator { - $maxSize = (float)$this->appConfig->getAppValueInt('indexing_max_size', Application::CC_MAX_SIZE); + $maxSize = (float)$this->appConfig->getAppValueInt('indexing_max_size', Application::CC_MAX_SIZE, true); $sources = []; $size = 0.0; diff --git a/lib/Settings/AdminSettings.php b/lib/Settings/AdminSettings.php index 26f9d3c6..69aac03d 100644 --- a/lib/Settings/AdminSettings.php +++ b/lib/Settings/AdminSettings.php @@ -41,12 +41,12 @@ public function __construct( public function getForm(): TemplateResponse { $stats = []; - $stats['installed_at'] = $this->appConfig->getAppValueInt('installed_time', 0); - if ($this->appConfig->getAppValueInt('last_indexed_time', 0) === 0) { + $stats['installed_at'] = $this->appConfig->getAppValueInt('installed_time', 0, true); + if ($this->appConfig->getAppValueInt('last_indexed_time', 0, true) === 0) { $stats['initial_indexing_complete'] = false; } else { $stats['initial_indexing_complete'] = true; - $stats['intial_indexing_completed_at'] = $this->appConfig->getAppValueInt('last_indexed_time', 0); + $stats['intial_indexing_completed_at'] = $this->appConfig->getAppValueInt('last_indexed_time', 0, true); } try { @@ -55,7 +55,9 @@ public function getForm(): TemplateResponse { $this->logger->error($e->getMessage(), ['exception' => $e]); $stats['eligible_files_count'] = 0; } - $stats['recorded_indexed_files_count'] = Util::numericToNumber($this->appConfig->getAppValueString('indexed_files_count', '0')); + $stats['recorded_indexed_files_count'] = Util::numericToNumber(intval( + $this->appConfig->getAppValueString('indexed_files_count', '0', false) + )); try { $stats['queued_actions_count'] = $this->actionService->count(); } catch (Exception $e) { diff --git a/lib/TaskProcessing/ContextChatProvider.php b/lib/TaskProcessing/ContextChatProvider.php index 1ad2c12b..c1eab886 100644 --- a/lib/TaskProcessing/ContextChatProvider.php +++ b/lib/TaskProcessing/ContextChatProvider.php @@ -252,7 +252,7 @@ private function indexFiles(string $userId, string ...$scopeList): array { } $indexedSources = []; - $maxSize = $this->appConfig->getAppValueInt('indexing_max_size', Application::CC_MAX_SIZE); + $maxSize = $this->appConfig->getAppValueInt('indexing_max_size', Application::CC_MAX_SIZE, true); foreach ($filteredNodes as $node) { try { if ($node['node'] instanceof File) { From eb0ef6f197d4a61d9852482fc3d446d13e38880a Mon Sep 17 00:00:00 2001 From: Anupam Kumar Date: Fri, 14 Nov 2025 18:17:30 +0530 Subject: [PATCH 2/6] feat: use lazy app config values and small fixes - use `isEnabledForAnyone` instead of `isInstalled` to check for app_api - type annotations for both OCP and the OCA IContentProvider - make `indexed_files_count` app config non-lazy Signed-off-by: Anupam Kumar --- lib/Logger.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/Logger.php b/lib/Logger.php index fce909fc..d5e5d9b2 100644 --- a/lib/Logger.php +++ b/lib/Logger.php @@ -34,7 +34,6 @@ public function __construct( public function getLogFilepath(): string { $default = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/context_chat.log'; - // todo: Legacy way was appconfig, now it's paralleled with the normal log config (?) return $this->appConfig->getAppValueString('logfile', $default, true); } From 81bebc3111c6aa2147003977990c135c4e651d7e Mon Sep 17 00:00:00 2001 From: Anupam Kumar Date: Mon, 24 Nov 2025 15:23:07 +0530 Subject: [PATCH 3/6] address review comments Signed-off-by: Anupam Kumar --- lib/BackgroundJobs/ActionJob.php | 2 +- lib/BackgroundJobs/FileSystemListenerJob.php | 2 +- lib/BackgroundJobs/IndexerJob.php | 14 +++++++------- lib/BackgroundJobs/RotateLogsJob.php | 2 +- lib/BackgroundJobs/SchedulerJob.php | 5 ++--- lib/BackgroundJobs/StorageCrawlJob.php | 4 ++-- lib/BackgroundJobs/SubmitContentJob.php | 2 +- lib/Command/Statistics.php | 8 ++++---- lib/Controller/ConfigController.php | 2 +- lib/Logger.php | 2 +- .../Version004000000Date20241217110041.php | 2 +- lib/Migration/Version4000Date20241108004215.php | 3 +-- lib/Public/ContentManager.php | 2 +- lib/Repair/AppInstallStep.php | 4 ++-- lib/Service/DiagnosticService.php | 4 ++-- lib/Service/LangRopeService.php | 8 ++++---- lib/Service/ProviderConfigService.php | 8 ++++---- lib/Service/ScanService.php | 2 +- lib/Settings/AdminSettings.php | 8 ++++---- lib/TaskProcessing/ContextChatProvider.php | 2 +- 20 files changed, 42 insertions(+), 44 deletions(-) diff --git a/lib/BackgroundJobs/ActionJob.php b/lib/BackgroundJobs/ActionJob.php index 91ed6f9d..e75c1647 100644 --- a/lib/BackgroundJobs/ActionJob.php +++ b/lib/BackgroundJobs/ActionJob.php @@ -38,7 +38,7 @@ public function __construct( } private function getJobInterval(): int { - return intval($this->appConfig->getAppValueString('action_job_interval', (string)(5 * 60), true)); // 5 minutes + return intval($this->appConfig->getAppValueString('action_job_interval', (string)(5 * 60), lazy: true)); // 5 minutes } protected function run($argument): void { diff --git a/lib/BackgroundJobs/FileSystemListenerJob.php b/lib/BackgroundJobs/FileSystemListenerJob.php index 842c7ae3..49efc1f1 100644 --- a/lib/BackgroundJobs/FileSystemListenerJob.php +++ b/lib/BackgroundJobs/FileSystemListenerJob.php @@ -48,7 +48,7 @@ public function __construct( } private function getJobInterval(): int { - return intval($this->appConfig->getAppValueString('fs_listener_job_interval', (string)(5 * 60), true)); // 5 minutes + return intval($this->appConfig->getAppValueString('fs_listener_job_interval', (string)(5 * 60), lazy: true)); // 5 minutes } protected function run($argument): void { diff --git a/lib/BackgroundJobs/IndexerJob.php b/lib/BackgroundJobs/IndexerJob.php index ec063dde..8f23cd98 100644 --- a/lib/BackgroundJobs/IndexerJob.php +++ b/lib/BackgroundJobs/IndexerJob.php @@ -91,7 +91,7 @@ public function run($argument): void { $this->storageId = $argument['storageId']; $this->rootId = $argument['rootId']; - if ($this->appConfig->getAppValueString('auto_indexing', 'true', true) === 'false') { + if ($this->appConfig->getAppValueString('auto_indexing', 'true', lazy: true) === 'false') { return; } $this->diagnosticService->sendJobTrigger(static::class, $this->getId()); @@ -149,19 +149,19 @@ public function run($argument): void { } protected function getBatchSize(): int { - return $this->appConfig->getAppValueInt('indexing_batch_size', self::DEFAULT_BATCH_SIZE, true); + return $this->appConfig->getAppValueInt('indexing_batch_size', self::DEFAULT_BATCH_SIZE, lazy: true); } protected function getMaxIndexingTime(): int { - return $this->appConfig->getAppValueInt('indexing_max_time', self::DEFAULT_MAX_INDEXING_TIME, true); + return $this->appConfig->getAppValueInt('indexing_max_time', self::DEFAULT_MAX_INDEXING_TIME, lazy: true); } protected function getJobInterval(): int { - return $this->appConfig->getAppValueInt('indexing_job_interval', self::DEFAULT_JOB_INTERVAL, true); + return $this->appConfig->getAppValueInt('indexing_job_interval', self::DEFAULT_JOB_INTERVAL, lazy: true); } protected function getMaxSize(): float { - return (float)$this->appConfig->getAppValueInt('indexing_max_size', Application::CC_MAX_SIZE, true); + return (float)$this->appConfig->getAppValueInt('indexing_max_size', Application::CC_MAX_SIZE, lazy: true); } /** @@ -321,7 +321,7 @@ protected function index(array $files): void { } private function setInitialIndexCompletion(): void { - if ($this->appConfig->getAppValueInt('last_indexed_time', 0, true) !== 0) { + if ($this->appConfig->getAppValueInt('last_indexed_time', 0, lazy: true) !== 0) { return; } try { @@ -345,7 +345,7 @@ private function setInitialIndexCompletion(): void { } $this->logger->info('Initial index completion detected, setting last indexed time'); - $this->appConfig->setAppValueInt('last_indexed_time', $this->timeFactory->getTime(), true); + $this->appConfig->setAppValueInt('last_indexed_time', $this->timeFactory->getTime(), lazy: true); } /** diff --git a/lib/BackgroundJobs/RotateLogsJob.php b/lib/BackgroundJobs/RotateLogsJob.php index 51c729fe..7dc1085a 100755 --- a/lib/BackgroundJobs/RotateLogsJob.php +++ b/lib/BackgroundJobs/RotateLogsJob.php @@ -28,7 +28,7 @@ public function __construct( protected function run($argument): void { $default = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/context_chat.log'; - $this->filePath = $this->appConfig->getAppValueString('logfile', $default, true); + $this->filePath = $this->appConfig->getAppValueString('logfile', $default, lazy: true); $this->maxSize = $this->config->getSystemValue('log_rotate_size', 100 * 1024 * 1024); diff --git a/lib/BackgroundJobs/SchedulerJob.php b/lib/BackgroundJobs/SchedulerJob.php index 66466486..2b98f573 100644 --- a/lib/BackgroundJobs/SchedulerJob.php +++ b/lib/BackgroundJobs/SchedulerJob.php @@ -34,9 +34,8 @@ public function __construct( * @throws Exception */ protected function run($argument): void { - // todo: non-lazy since this needs to change often in one process, like in the diagnostics service - $this->appConfig->setAppValueString('indexed_files_count', (string)0, false); - $this->appConfig->setAppValueInt('last_indexed_time', 0, true); + $this->appConfig->setAppValueString('indexed_files_count', (string)0, lazy: true); + $this->appConfig->setAppValueInt('last_indexed_time', 0, lazy: true); foreach ($this->storageService->getMounts() as $mount) { $this->logger->debug('Scheduling StorageCrawlJob storage_id=' . $mount['storage_id'] . ' root_id=' . $mount['root_id' ] . 'override_root=' . $mount['overridden_root']); $this->jobList->add(StorageCrawlJob::class, [ diff --git a/lib/BackgroundJobs/StorageCrawlJob.php b/lib/BackgroundJobs/StorageCrawlJob.php index 134f33ec..1447fed5 100644 --- a/lib/BackgroundJobs/StorageCrawlJob.php +++ b/lib/BackgroundJobs/StorageCrawlJob.php @@ -90,7 +90,7 @@ protected function run($argument): void { if ($lastSuccessfulFileId !== -1) { // the last job to set this value will win - $this->appConfig->setAppValueInt('last_indexed_file_id', $lastSuccessfulFileId, true); + $this->appConfig->setAppValueInt('last_indexed_file_id', $lastSuccessfulFileId, lazy: true); } } } finally { @@ -99,6 +99,6 @@ protected function run($argument): void { } protected function getJobInterval(): int { - return $this->appConfig->getAppValueInt('crawl_job_interval', self::DEFAULT_JOB_INTERVAL, true); + return $this->appConfig->getAppValueInt('crawl_job_interval', self::DEFAULT_JOB_INTERVAL, lazy: true); } } diff --git a/lib/BackgroundJobs/SubmitContentJob.php b/lib/BackgroundJobs/SubmitContentJob.php index 1975e18c..3e90c6b1 100644 --- a/lib/BackgroundJobs/SubmitContentJob.php +++ b/lib/BackgroundJobs/SubmitContentJob.php @@ -63,7 +63,7 @@ protected function run($argument): void { return; } - $maxSize = $this->appConfig->getAppValueInt('indexing_max_size', Application::CC_MAX_SIZE, true); + $maxSize = $this->appConfig->getAppValueInt('indexing_max_size', Application::CC_MAX_SIZE, lazy: true); if (empty($entities)) { return; diff --git a/lib/Command/Statistics.php b/lib/Command/Statistics.php index e0868e47..6282c1d8 100644 --- a/lib/Command/Statistics.php +++ b/lib/Command/Statistics.php @@ -42,11 +42,11 @@ protected function configure() { protected function execute(InputInterface $input, OutputInterface $output): int { $output->writeln('ContextChat statistics:'); - if ($this->appConfig->getAppValueInt('last_indexed_time', 0, true) === 0) { + if ($this->appConfig->getAppValueInt('last_indexed_time', 0, lazy: true) === 0) { $output->writeln('The indexing is not complete yet.'); } else { - $installedTime = $this->appConfig->getAppValueInt('installed_time', 0, true); - $lastIndexedTime = $this->appConfig->getAppValueInt('last_indexed_time', 0, true); + $installedTime = $this->appConfig->getAppValueInt('installed_time', 0, lazy: true); + $lastIndexedTime = $this->appConfig->getAppValueInt('last_indexed_time', 0, lazy: true); $indexTime = $lastIndexedTime - $installedTime; $output->writeln('Installed time: ' . (new \DateTime('@' . $installedTime))->format('Y-m-d H:i') . ' UTC'); @@ -66,7 +66,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $queuedDocumentsCount = $this->contentQueue->count(); $output->writeln('Queued documents (without files):' . var_export($queuedDocumentsCount, true)); - $indexFilesCount = Util::numericToNumber(intval($this->appConfig->getAppValueString('indexed_files_count', '0', false))); + $indexFilesCount = Util::numericToNumber(intval($this->appConfig->getAppValueString('indexed_files_count', '0', lazy: true))); $output->writeln('Files successfully sent to backend: ' . strval($indexFilesCount)); $indexedDocumentsCount = $this->langRopeService->getIndexedDocumentsCounts(); diff --git a/lib/Controller/ConfigController.php b/lib/Controller/ConfigController.php index e1ee7d4b..67758d80 100644 --- a/lib/Controller/ConfigController.php +++ b/lib/Controller/ConfigController.php @@ -51,7 +51,7 @@ public function setConfig(array $values): DataResponse { */ public function setAdminConfig(array $values): DataResponse { foreach ($values as $key => $value) { - $this->appConfig->setAppValueString($key, $value, true); + $this->appConfig->setAppValueString($key, $value, lazy: true); } return new DataResponse(1); } diff --git a/lib/Logger.php b/lib/Logger.php index d5e5d9b2..25058100 100644 --- a/lib/Logger.php +++ b/lib/Logger.php @@ -34,7 +34,7 @@ public function __construct( public function getLogFilepath(): string { $default = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/context_chat.log'; - return $this->appConfig->getAppValueString('logfile', $default, true); + return $this->appConfig->getAppValueString('logfile', $default, lazy: true); } public function emergency(Stringable|string $message, array $context = []): void { diff --git a/lib/Migration/Version004000000Date20241217110041.php b/lib/Migration/Version004000000Date20241217110041.php index b964b4f3..002bf40b 100644 --- a/lib/Migration/Version004000000Date20241217110041.php +++ b/lib/Migration/Version004000000Date20241217110041.php @@ -95,7 +95,7 @@ public function postSchemaChange(IOutput $output, Closure $schemaClosure, array } $output->advance(1); - $this->appConfig->setAppValueString('providers', '', true); + $this->appConfig->setAppValueString('providers', '', lazy: true); $output->advance(1); $this->jobList->add(SchedulerJob::class); diff --git a/lib/Migration/Version4000Date20241108004215.php b/lib/Migration/Version4000Date20241108004215.php index e240b9e7..215cee92 100644 --- a/lib/Migration/Version4000Date20241108004215.php +++ b/lib/Migration/Version4000Date20241108004215.php @@ -77,8 +77,7 @@ public function postSchemaChange(IOutput $output, Closure $schemaClosure, array } $output->advance(1); - // todo: maybe migrations also need to use the newer app config service? - $this->appConfig->setAppValueString('providers', '', true); + $this->appConfig->setAppValueString('providers', '', lazy: true); $output->advance(1); $this->jobList->add(SchedulerJob::class); diff --git a/lib/Public/ContentManager.php b/lib/Public/ContentManager.php index e6840f28..54be3e5c 100644 --- a/lib/Public/ContentManager.php +++ b/lib/Public/ContentManager.php @@ -46,7 +46,7 @@ public function __construct( * @since 4.6.0 */ public function isContextChatAvailable(): bool { - return $this->appConfig->getAppValueString('backend_init', 'false', true) === 'true'; + return $this->appConfig->getAppValueString('backend_init', 'false', lazy: true) === 'true'; } /** diff --git a/lib/Repair/AppInstallStep.php b/lib/Repair/AppInstallStep.php index d1241df2..d3a9735a 100644 --- a/lib/Repair/AppInstallStep.php +++ b/lib/Repair/AppInstallStep.php @@ -34,9 +34,9 @@ public function getName(): string { * @param IOutput $output */ public function run(IOutput $output): void { - if ($this->appConfig->getAppValueInt('installed_time', 0, true) === 0) { + if ($this->appConfig->getAppValueInt('installed_time', 0, lazy: true) === 0) { $this->logger->info('Setting up Context Chat for the first time'); - $this->appConfig->setAppValueInt('installed_time', time(), true); + $this->appConfig->setAppValueInt('installed_time', time(), lazy: true); } $providerConfigService = new ProviderConfigService($this->appConfig); diff --git a/lib/Service/DiagnosticService.php b/lib/Service/DiagnosticService.php index 48abfb4c..ab854694 100644 --- a/lib/Service/DiagnosticService.php +++ b/lib/Service/DiagnosticService.php @@ -66,10 +66,10 @@ public function sendIndexedFiles(int $count): void { 'indexed_files_count', (string)Util::numericToNumber( floatval($count) + floatval(Util::numericToNumber(intval( - $this->appConfig->getAppValueString('indexed_files_count', '0', false) + $this->appConfig->getAppValueString('indexed_files_count', '0', lazy: true) ))) ), - false, + lazy: true, ); } } diff --git a/lib/Service/LangRopeService.php b/lib/Service/LangRopeService.php index 170be3dc..6be3ff33 100644 --- a/lib/Service/LangRopeService.php +++ b/lib/Service/LangRopeService.php @@ -66,7 +66,7 @@ private function requestToExApp( } // backend init check - $backendInit = $this->appConfig->getAppValueString('backend_init', 'false', true); + $backendInit = $this->appConfig->getAppValueString('backend_init', 'false', lazy: true); if ($backendInit !== 'true') { $enabledResponse = $appApiFunctions->exAppRequest('context_chat_backend', '/enabled', $this->userId, 'GET'); @@ -88,9 +88,9 @@ private function requestToExApp( } if (isset($enabledResponse['enabled']) && $enabledResponse['enabled'] === true) { - $this->appConfig->setAppValueString('backend_init', 'true', true); + $this->appConfig->setAppValueString('backend_init', 'true', lazy: true); } else { - $this->appConfig->setAppValueString('backend_init', 'false', true); + $this->appConfig->setAppValueString('backend_init', 'false', lazy: true); throw new RuntimeException('Context Chat backend is not ready yet. Please wait a while before trying again.'); } } @@ -98,7 +98,7 @@ private function requestToExApp( $timeout = $this->appConfig->getAppValueString( 'request_timeout', strval(Application::CC_DEFAULT_REQUEST_TIMEOUT), - true, + lazy: true, ); $options = [ 'timeout' => $timeout, diff --git a/lib/Service/ProviderConfigService.php b/lib/Service/ProviderConfigService.php index 503368ad..344c98e0 100644 --- a/lib/Service/ProviderConfigService.php +++ b/lib/Service/ProviderConfigService.php @@ -78,14 +78,14 @@ public function getProvider(string $providerKey): ?array { */ public function getProviders(): array { $providers = []; - $providersString = $this->appConfig->getAppValueString('providers', '', true); + $providersString = $this->appConfig->getAppValueString('providers', '', lazy: true); if ($providersString !== '') { $providers = json_decode($providersString, true); if ($providers === null || !$this->validateProvidersArray($providers)) { $providers = []; - $this->appConfig->setAppValueString('providers', '', true); + $this->appConfig->setAppValueString('providers', '', lazy: true); } } @@ -109,7 +109,7 @@ public function updateProvider( 'isInitiated' => $isInitiated, 'classString' => $providerClass, ]; - $this->appConfig->setAppValueString('providers', json_encode($providers), true); + $this->appConfig->setAppValueString('providers', json_encode($providers), lazy: true); } /** @@ -129,7 +129,7 @@ public function removeProvider(string $appId, ?string $providerId = null): void } } - $this->appConfig->setAppValueString('providers', json_encode($providers), true); + $this->appConfig->setAppValueString('providers', json_encode($providers), lazy: true); } /** diff --git a/lib/Service/ScanService.php b/lib/Service/ScanService.php index c92ab835..bdf7a914 100644 --- a/lib/Service/ScanService.php +++ b/lib/Service/ScanService.php @@ -49,7 +49,7 @@ public function scanUserFiles(string $userId, array $mimeTypeFilter, ?string $di * @return \Generator */ public function scanDirectory(array $mimeTypeFilter, Folder $directory): \Generator { - $maxSize = (float)$this->appConfig->getAppValueInt('indexing_max_size', Application::CC_MAX_SIZE, true); + $maxSize = (float)$this->appConfig->getAppValueInt('indexing_max_size', Application::CC_MAX_SIZE, lazy: true); $sources = []; $size = 0.0; diff --git a/lib/Settings/AdminSettings.php b/lib/Settings/AdminSettings.php index 69aac03d..721754ab 100644 --- a/lib/Settings/AdminSettings.php +++ b/lib/Settings/AdminSettings.php @@ -41,12 +41,12 @@ public function __construct( public function getForm(): TemplateResponse { $stats = []; - $stats['installed_at'] = $this->appConfig->getAppValueInt('installed_time', 0, true); - if ($this->appConfig->getAppValueInt('last_indexed_time', 0, true) === 0) { + $stats['installed_at'] = $this->appConfig->getAppValueInt('installed_time', 0, lazy: true); + if ($this->appConfig->getAppValueInt('last_indexed_time', 0, lazy: true) === 0) { $stats['initial_indexing_complete'] = false; } else { $stats['initial_indexing_complete'] = true; - $stats['intial_indexing_completed_at'] = $this->appConfig->getAppValueInt('last_indexed_time', 0, true); + $stats['intial_indexing_completed_at'] = $this->appConfig->getAppValueInt('last_indexed_time', 0, lazy: true); } try { @@ -56,7 +56,7 @@ public function getForm(): TemplateResponse { $stats['eligible_files_count'] = 0; } $stats['recorded_indexed_files_count'] = Util::numericToNumber(intval( - $this->appConfig->getAppValueString('indexed_files_count', '0', false) + $this->appConfig->getAppValueString('indexed_files_count', '0', lazy: true) )); try { $stats['queued_actions_count'] = $this->actionService->count(); diff --git a/lib/TaskProcessing/ContextChatProvider.php b/lib/TaskProcessing/ContextChatProvider.php index c1eab886..032c9ab1 100644 --- a/lib/TaskProcessing/ContextChatProvider.php +++ b/lib/TaskProcessing/ContextChatProvider.php @@ -252,7 +252,7 @@ private function indexFiles(string $userId, string ...$scopeList): array { } $indexedSources = []; - $maxSize = $this->appConfig->getAppValueInt('indexing_max_size', Application::CC_MAX_SIZE, true); + $maxSize = $this->appConfig->getAppValueInt('indexing_max_size', Application::CC_MAX_SIZE, lazy: true); foreach ($filteredNodes as $node) { try { if ($node['node'] instanceof File) { From 9976be02bb9b3a9fa1d6c91db1e31b30d350ac25 Mon Sep 17 00:00:00 2001 From: Anupam Kumar Date: Mon, 24 Nov 2025 17:16:56 +0530 Subject: [PATCH 4/6] migrate config values to be lazy Signed-off-by: Anupam Kumar --- appinfo/info.xml | 2 +- .../Version005000001Date20251124093628.php | 72 +++++++++++++++++++ .../Version4000Date20241108004215.php | 1 - 3 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 lib/Migration/Version005000001Date20251124093628.php diff --git a/appinfo/info.xml b/appinfo/info.xml index 566f909f..30f095f7 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -22,7 +22,7 @@ Setup background job workers as described here: https://docs.nextcloud.com/serve Note: Refer to the [Context Chat Backend's readme](https://github.com/nextcloud/context_chat_backend/?tab=readme-ov-file) and the [AppAPI's documentation](https://cloud-py-api.github.io/app_api/) for help with setup of AppAPI's deploy daemon. ]]> - 5.0.0 + 5.0.1 agpl Julien Veyssier Anupam Kumar diff --git a/lib/Migration/Version005000001Date20251124093628.php b/lib/Migration/Version005000001Date20251124093628.php new file mode 100644 index 00000000..26ae498c --- /dev/null +++ b/lib/Migration/Version005000001Date20251124093628.php @@ -0,0 +1,72 @@ +hasTable('appconfig')) { + return null; + } + + $qb = $this->connection->getQueryBuilder(); + $qb->update('appconfig') + ->set('lazy', $qb->createNamedParameter(1, IQueryBuilder::PARAM_INT)) + ->where( + $qb->expr()->eq('appid', $qb->createNamedParameter(Application::APP_ID, IQueryBuilder::PARAM_STR)) + ) + ->andWhere( + $qb->expr()->in('configkey', $qb->createNamedParameter(self::$configKeys, IQueryBuilder::PARAM_STR_ARRAY)) + ); + $qb->executeStatement(); + + return $schema; + } +} diff --git a/lib/Migration/Version4000Date20241108004215.php b/lib/Migration/Version4000Date20241108004215.php index 215cee92..f8835d91 100644 --- a/lib/Migration/Version4000Date20241108004215.php +++ b/lib/Migration/Version4000Date20241108004215.php @@ -10,7 +10,6 @@ namespace OCA\ContextChat\Migration; use Closure; -use OCA\ContextChat\AppInfo\Application; use OCA\ContextChat\BackgroundJobs\IndexerJob; use OCA\ContextChat\BackgroundJobs\InitialContentImportJob; use OCA\ContextChat\BackgroundJobs\SchedulerJob; From 81f2c49ae2f959d2c7e49d73a9c8fda5848ac8cf Mon Sep 17 00:00:00 2001 From: Anupam Kumar Date: Tue, 25 Nov 2025 17:44:22 +0530 Subject: [PATCH 5/6] use IAppConfig instead of DB query to make lazy configs Signed-off-by: Anupam Kumar --- .../Version005000001Date20251124093628.php | 71 ++++++++++--------- 1 file changed, 38 insertions(+), 33 deletions(-) diff --git a/lib/Migration/Version005000001Date20251124093628.php b/lib/Migration/Version005000001Date20251124093628.php index 26ae498c..14945bbe 100644 --- a/lib/Migration/Version005000001Date20251124093628.php +++ b/lib/Migration/Version005000001Date20251124093628.php @@ -10,35 +10,37 @@ namespace OCA\ContextChat\Migration; use Closure; -use OCA\ContextChat\AppInfo\Application; +use OCP\AppFramework\Services\IAppConfig; use OCP\DB\ISchemaWrapper; -use OCP\DB\QueryBuilder\IQueryBuilder; -use OCP\IDBConnection; use OCP\Migration\IOutput; use OCP\Migration\SimpleMigrationStep; use Override; class Version005000001Date20251124093628 extends SimpleMigrationStep { private static array $configKeys = [ - 'action_job_interval', - 'auto_indexing', - 'backend_init', - 'crawl_job_interval', - 'fs_listener_job_interval', - 'indexed_files_count', - 'indexing_batch_size', - 'indexing_job_interval', - 'indexing_max_size', - 'indexing_max_time', - 'installed_time', - 'last_indexed_file_id', - 'last_indexed_time', - 'logfile', - 'providers', + 'int' => [ + 'crawl_job_interval', + 'indexing_batch_size', + 'indexing_job_interval', + 'indexing_max_size', + 'indexing_max_time', + 'installed_time', + 'last_indexed_file_id', + 'last_indexed_time' + ], + 'string' => [ + 'action_job_interval', + 'auto_indexing', + 'backend_init', + 'fs_listener_job_interval', + 'indexed_files_count', + 'logfile', + 'providers' + ] ]; public function __construct( - private IDBConnection $connection, + private IAppConfig $appConfig, ) { } @@ -50,23 +52,26 @@ public function __construct( */ #[Override] public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) { - $schema = $schemaClosure(); + $allSetKeys = $this->appConfig->getAppKeys(); - if (!$schema->hasTable('appconfig')) { - return null; + foreach (self::$configKeys['int'] as $key) { + // skip if not already set + if (!in_array($key, $allSetKeys)) { + continue; + } + $value = $this->appConfig->getAppValueInt($key); + $this->appConfig->setAppValueInt($key, $value, lazy: true); } - $qb = $this->connection->getQueryBuilder(); - $qb->update('appconfig') - ->set('lazy', $qb->createNamedParameter(1, IQueryBuilder::PARAM_INT)) - ->where( - $qb->expr()->eq('appid', $qb->createNamedParameter(Application::APP_ID, IQueryBuilder::PARAM_STR)) - ) - ->andWhere( - $qb->expr()->in('configkey', $qb->createNamedParameter(self::$configKeys, IQueryBuilder::PARAM_STR_ARRAY)) - ); - $qb->executeStatement(); + foreach (self::$configKeys['string'] as $key) { + // skip if not already set + if (!in_array($key, $allSetKeys)) { + continue; + } + $value = $this->appConfig->getAppValueString($key); + $this->appConfig->setAppValueString($key, $value, lazy: true); + } - return $schema; + return null; } } From 8bc499e69e222ab160dacbb455cfc6606b836376 Mon Sep 17 00:00:00 2001 From: Anupam Kumar Date: Thu, 4 Dec 2025 19:32:36 +0530 Subject: [PATCH 6/6] fix(ci): set fs_listener_job_interval and action_job_interval as strings Signed-off-by: Anupam Kumar --- .github/workflows/integration-test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 3e5ac8af..637c99a4 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -573,8 +573,8 @@ jobs: # Run cron in speed mode: Set interval to 0 minutes ./occ config:app:set --value 30 --type integer context_chat indexing_job_interval # 30 seconds ./occ config:app:set --value 10 --type integer context_chat crawl_job_interval # 10 seconds - ./occ config:app:set --value 10 --type integer context_chat action_job_interval # 10 seconds - ./occ config:app:set --value 10 --type integer context_chat fs_listener_job_interval # 10 seconds + ./occ config:app:set --value '10' --type string context_chat action_job_interval # 10 seconds + ./occ config:app:set --value '10' --type string context_chat fs_listener_job_interval # 10 seconds for i in {1..100}; do php cron.php & # Starting with stable31 we can use -v here for better visibility wait @@ -822,8 +822,8 @@ jobs: # Run cron in speed mode ./occ config:app:set --value 30 --type integer context_chat indexing_job_interval # 30 seconds ./occ config:app:set --value 10 --type integer context_chat crawl_job_interval # 10 seconds - ./occ config:app:set --value 10 --type integer context_chat action_job_interval # 10 seconds - ./occ config:app:set --value 10 --type integer context_chat fs_listener_job_interval # 10 seconds + ./occ config:app:set --value '10' --type string context_chat action_job_interval # 10 seconds + ./occ config:app:set --value '10' --type string context_chat fs_listener_job_interval # 10 seconds # Run normal indexing jobs which will only pick up welcome.txt etc for i in {1..10}; do php cron.php & # Starting with stable31 we can use -v here for better visibility