diff options
author | Marcel Klehr <mklehr@gmx.net> | 2023-11-03 16:22:54 +0100 |
---|---|---|
committer | Marcel Klehr <mklehr@gmx.net> | 2023-11-03 16:22:54 +0100 |
commit | 181f819e417a1818f37200f9071fa632c82a0fc2 (patch) | |
tree | bbdf2d6a816aa3caa7cf402e63cc520c6cbd67f1 /lib/private/TextProcessing/Manager.php | |
parent | b038dbe0aef8c8680bd4f9075f00d8303338f518 (diff) | |
download | nextcloud-server-181f819e417a1818f37200f9071fa632c82a0fc2.tar.gz nextcloud-server-181f819e417a1818f37200f9071fa632c82a0fc2.zip |
enh(TextProcessing): Add IProvider2
- allow providers to obtain current task's userId
- allow providers to expose average task runtime
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
Diffstat (limited to 'lib/private/TextProcessing/Manager.php')
-rw-r--r-- | lib/private/TextProcessing/Manager.php | 69 |
1 files changed, 55 insertions, 14 deletions
diff --git a/lib/private/TextProcessing/Manager.php b/lib/private/TextProcessing/Manager.php index b9cb06c298e..bee70b53a33 100644 --- a/lib/private/TextProcessing/Manager.php +++ b/lib/private/TextProcessing/Manager.php @@ -28,6 +28,7 @@ namespace OC\TextProcessing; use OC\AppFramework\Bootstrap\Coordinator; use OC\TextProcessing\Db\Task as DbTask; use OCP\IConfig; +use OCP\TextProcessing\IProvider2; use OCP\TextProcessing\Task; use OCP\TextProcessing\Task as OCPTask; use OC\TextProcessing\Db\TaskMapper; @@ -114,19 +115,7 @@ class Manager implements IManager { if (!$this->canHandleTask($task)) { throw new PreConditionNotMetException('No text processing provider is installed that can handle this task'); } - $providers = $this->getProviders(); - $json = $this->config->getAppValue('core', 'ai.textprocessing_provider_preferences', ''); - if ($json !== '') { - $preferences = json_decode($json, true); - if (isset($preferences[$task->getType()])) { - // If a preference for this task type is set, move the preferred provider to the start - $provider = current(array_filter($providers, fn ($provider) => $provider::class === $preferences[$task->getType()])); - if ($provider !== false) { - $providers = array_filter($providers, fn ($p) => $p !== $provider); - array_unshift($providers, $provider); - } - } - } + $providers = $this->getPreferredProviders($task); foreach ($providers as $provider) { if (!$task->canUseProvider($provider)) { @@ -134,6 +123,11 @@ class Manager implements IManager { } try { $task->setStatus(OCPTask::STATUS_RUNNING); + if ($provider instanceof IProvider2) { + $completionExpectedAt = new \DateTime('now'); + $completionExpectedAt->add(new \DateInterval('PT'.$provider->getExpectedRuntime().'S')); + $task->setCompletionExpectedAt($completionExpectedAt); + } if ($task->getId() === null) { $taskEntity = $this->taskMapper->insert(DbTask::fromPublicTask($task)); $task->setId($taskEntity->getId()); @@ -158,18 +152,25 @@ class Manager implements IManager { } } + $task->setStatus(OCPTask::STATUS_FAILED); + $this->taskMapper->update(DbTask::fromPublicTask($task)); throw new RuntimeException('Could not run task'); } /** * @inheritDoc - * @throws Exception */ public function scheduleTask(OCPTask $task): void { if (!$this->canHandleTask($task)) { throw new PreConditionNotMetException('No LanguageModel provider is installed that can handle this task'); } $task->setStatus(OCPTask::STATUS_SCHEDULED); + [$provider, ] = $this->getPreferredProviders($task); + if ($provider instanceof IProvider2) { + $completionExpectedAt = new \DateTime('now'); + $completionExpectedAt->add(new \DateInterval('PT'.$provider->getExpectedRuntime().'S')); + $task->setCompletionExpectedAt($completionExpectedAt); + } $taskEntity = DbTask::fromPublicTask($task); $this->taskMapper->insert($taskEntity); $task->setId($taskEntity->getId()); @@ -181,6 +182,25 @@ class Manager implements IManager { /** * @inheritDoc */ + public function runOrScheduleTask(OCPTask $task) : bool { + if (!$this->canHandleTask($task)) { + throw new PreConditionNotMetException('No LanguageModel provider is installed that can handle this task'); + } + [$provider,] = $this->getPreferredProviders($task); + $maxExecutionTime = (int) ini_get('max_execution_time'); + // Offload the task to a background job if the expected runtime of the likely provider is longer than 80% of our max execution time + // or if the provider doesn't provide a getExpectedRuntime() method + if (!$provider instanceof IProvider2 || $provider->getExpectedRuntime() > $maxExecutionTime * 0.8) { + $this->scheduleTask($task); + return false; + } + $this->runTask($task); + return true; + } + + /** + * @inheritDoc + */ public function deleteTask(Task $task): void { $taskEntity = DbTask::fromPublicTask($task); $this->taskMapper->delete($taskEntity); @@ -253,4 +273,25 @@ class Manager implements IManager { throw new RuntimeException('Failure while trying to find tasks by appId and identifier: ' . $e->getMessage(), 0, $e); } } + + /** + * @param OCPTask $task + * @return IProvider[] + */ + public function getPreferredProviders(OCPTask $task): array { + $providers = $this->getProviders(); + $json = $this->config->getAppValue('core', 'ai.textprocessing_provider_preferences', ''); + if ($json !== '') { + $preferences = json_decode($json, true); + if (isset($preferences[$task->getType()])) { + // If a preference for this task type is set, move the preferred provider to the start + $provider = current(array_filter($providers, fn ($provider) => $provider::class === $preferences[$task->getType()])); + if ($provider !== false) { + $providers = array_filter($providers, fn ($p) => $p !== $provider); + array_unshift($providers, $provider); + } + } + } + return $providers; + } } |