From 181f819e417a1818f37200f9071fa632c82a0fc2 Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Fri, 3 Nov 2023 16:22:54 +0100 Subject: enh(TextProcessing): Add IProvider2 - allow providers to obtain current task's userId - allow providers to expose average task runtime Signed-off-by: Marcel Klehr --- lib/public/TextProcessing/Task.php | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'lib/public/TextProcessing/Task.php') diff --git a/lib/public/TextProcessing/Task.php b/lib/public/TextProcessing/Task.php index 446e414cb04..16850348358 100644 --- a/lib/public/TextProcessing/Task.php +++ b/lib/public/TextProcessing/Task.php @@ -35,6 +35,7 @@ namespace OCP\TextProcessing; final class Task implements \JsonSerializable { protected ?int $id = null; protected ?string $output = null; + private ?\DateTime $completionExpectedAt = null; /** * @since 27.1.0 @@ -92,12 +93,15 @@ final class Task implements \JsonSerializable { /** * @psalm-param P $provider - * @param IProvider $provider + * @param IProvider|IProvider2 $provider * @return string * @since 27.1.0 */ - public function visitProvider(IProvider $provider): string { + public function visitProvider(IProvider|IProvider2 $provider): string { if ($this->canUseProvider($provider)) { + if ($provider instanceof IProvider2) { + $provider->setUserId($this->getUserId()); + } return $provider->process($this->getInput()); } else { throw new \RuntimeException('Task of type ' . $this->getType() . ' cannot visit provider with task type ' . $provider->getTaskType()); @@ -203,7 +207,7 @@ final class Task implements \JsonSerializable { } /** - * @psalm-return array{id: ?int, type: S, status: 0|1|2|3|4, userId: ?string, appId: string, input: string, output: ?string, identifier: string} + * @psalm-return array{id: ?int, type: S, status: 0|1|2|3|4, userId: ?string, appId: string, input: string, output: ?string, identifier: string, completionExpectedAt: ?int} * @since 27.1.0 */ public function jsonSerialize(): array { @@ -216,6 +220,15 @@ final class Task implements \JsonSerializable { 'input' => $this->getInput(), 'output' => $this->getOutput(), 'identifier' => $this->getIdentifier(), + 'completionExpectedAt' => $this->getCompletionExpectedAt()?->getTimestamp(), ]; } + +final public function setCompletionExpectedAt(\DateTime $completionExpectedAt): void { + $this->completionExpectedAt = $completionExpectedAt; +} + +final public function getCompletionExpectedAt(): ?\DateTime { + return $this->completionExpectedAt; +} } -- cgit v1.2.3 From fecf6425cff5d3d67fd874780189d053e70a0074 Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Mon, 6 Nov 2023 14:53:20 +0100 Subject: fix: psalm issues and coding style Signed-off-by: Marcel Klehr --- .../Exception/TaskFailureException.php | 5 ++++- lib/public/TextProcessing/Task.php | 21 +++++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) (limited to 'lib/public/TextProcessing/Task.php') diff --git a/lib/public/TextProcessing/Exception/TaskFailureException.php b/lib/public/TextProcessing/Exception/TaskFailureException.php index 5f7b308757b..300864711e7 100644 --- a/lib/public/TextProcessing/Exception/TaskFailureException.php +++ b/lib/public/TextProcessing/Exception/TaskFailureException.php @@ -2,6 +2,9 @@ namespace OCP\TextProcessing\Exception; +/** + * Exception thrown when a task failed + * @since 28.0.0 + */ class TaskFailureException extends \RuntimeException { - } diff --git a/lib/public/TextProcessing/Task.php b/lib/public/TextProcessing/Task.php index 16850348358..f6b3a1a6a42 100644 --- a/lib/public/TextProcessing/Task.php +++ b/lib/public/TextProcessing/Task.php @@ -224,11 +224,20 @@ final class Task implements \JsonSerializable { ]; } -final public function setCompletionExpectedAt(\DateTime $completionExpectedAt): void { - $this->completionExpectedAt = $completionExpectedAt; -} + /** + * @param null|\DateTime $completionExpectedAt + * @return void + * @since 28.0.0 + */ + final public function setCompletionExpectedAt(?\DateTime $completionExpectedAt): void { + $this->completionExpectedAt = $completionExpectedAt; + } -final public function getCompletionExpectedAt(): ?\DateTime { - return $this->completionExpectedAt; -} + /** + * @return \DateTime|null + * @since 28.0.0 + */ + final public function getCompletionExpectedAt(): ?\DateTime { + return $this->completionExpectedAt; + } } -- cgit v1.2.3 From 17e7b6c7110e11c977852da91d62cab12cde0b49 Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Tue, 7 Nov 2023 12:02:03 +0100 Subject: fix: split IProvider2 into two more verbose interfaces Signed-off-by: Marcel Klehr --- lib/composer/composer/autoload_classmap.php | 4 ++ lib/composer/composer/autoload_static.php | 4 ++ lib/private/TextProcessing/Manager.php | 8 ++-- lib/public/TextProcessing/IProvider2.php | 48 ---------------------- .../IProviderWithExpectedRuntime.php | 42 +++++++++++++++++++ lib/public/TextProcessing/IProviderWithUserId.php | 41 ++++++++++++++++++ lib/public/TextProcessing/Task.php | 6 +-- 7 files changed, 98 insertions(+), 55 deletions(-) delete mode 100644 lib/public/TextProcessing/IProvider2.php create mode 100644 lib/public/TextProcessing/IProviderWithExpectedRuntime.php create mode 100644 lib/public/TextProcessing/IProviderWithUserId.php (limited to 'lib/public/TextProcessing/Task.php') diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index b2d0b225574..3367077d833 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -666,10 +666,13 @@ return array( 'OCP\\TextProcessing\\Events\\AbstractTextProcessingEvent' => $baseDir . '/lib/public/TextProcessing/Events/AbstractTextProcessingEvent.php', 'OCP\\TextProcessing\\Events\\TaskFailedEvent' => $baseDir . '/lib/public/TextProcessing/Events/TaskFailedEvent.php', 'OCP\\TextProcessing\\Events\\TaskSuccessfulEvent' => $baseDir . '/lib/public/TextProcessing/Events/TaskSuccessfulEvent.php', + 'OCP\\TextProcessing\\Exception\\TaskFailureException' => $baseDir . '/lib/public/TextProcessing/Exception/TaskFailureException.php', 'OCP\\TextProcessing\\FreePromptTaskType' => $baseDir . '/lib/public/TextProcessing/FreePromptTaskType.php', 'OCP\\TextProcessing\\HeadlineTaskType' => $baseDir . '/lib/public/TextProcessing/HeadlineTaskType.php', 'OCP\\TextProcessing\\IManager' => $baseDir . '/lib/public/TextProcessing/IManager.php', 'OCP\\TextProcessing\\IProvider' => $baseDir . '/lib/public/TextProcessing/IProvider.php', + 'OCP\\TextProcessing\\IProviderWithExpectedRuntime' => $baseDir . '/lib/public/TextProcessing/IProviderWithExpectedRuntime.php', + 'OCP\\TextProcessing\\IProviderWithUserId' => $baseDir . '/lib/public/TextProcessing/IProviderWithUserId.php', 'OCP\\TextProcessing\\ITaskType' => $baseDir . '/lib/public/TextProcessing/ITaskType.php', 'OCP\\TextProcessing\\SummaryTaskType' => $baseDir . '/lib/public/TextProcessing/SummaryTaskType.php', 'OCP\\TextProcessing\\Task' => $baseDir . '/lib/public/TextProcessing/Task.php', @@ -1196,6 +1199,7 @@ return array( 'OC\\Core\\Migrations\\Version28000Date20230728104802' => $baseDir . '/core/Migrations/Version28000Date20230728104802.php', 'OC\\Core\\Migrations\\Version28000Date20230803221055' => $baseDir . '/core/Migrations/Version28000Date20230803221055.php', 'OC\\Core\\Migrations\\Version28000Date20230906104802' => $baseDir . '/core/Migrations/Version28000Date20230906104802.php', + 'OC\\Core\\Migrations\\Version28000Date20231103104802' => $baseDir . '/core/Migrations/Version28000Date20231103104802.php', 'OC\\Core\\Notification\\CoreNotifier' => $baseDir . '/core/Notification/CoreNotifier.php', 'OC\\Core\\Service\\LoginFlowV2Service' => $baseDir . '/core/Service/LoginFlowV2Service.php', 'OC\\DB\\Adapter' => $baseDir . '/lib/private/DB/Adapter.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 7e73255b29b..0f7e2de64ef 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -699,10 +699,13 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OCP\\TextProcessing\\Events\\AbstractTextProcessingEvent' => __DIR__ . '/../../..' . '/lib/public/TextProcessing/Events/AbstractTextProcessingEvent.php', 'OCP\\TextProcessing\\Events\\TaskFailedEvent' => __DIR__ . '/../../..' . '/lib/public/TextProcessing/Events/TaskFailedEvent.php', 'OCP\\TextProcessing\\Events\\TaskSuccessfulEvent' => __DIR__ . '/../../..' . '/lib/public/TextProcessing/Events/TaskSuccessfulEvent.php', + 'OCP\\TextProcessing\\Exception\\TaskFailureException' => __DIR__ . '/../../..' . '/lib/public/TextProcessing/Exception/TaskFailureException.php', 'OCP\\TextProcessing\\FreePromptTaskType' => __DIR__ . '/../../..' . '/lib/public/TextProcessing/FreePromptTaskType.php', 'OCP\\TextProcessing\\HeadlineTaskType' => __DIR__ . '/../../..' . '/lib/public/TextProcessing/HeadlineTaskType.php', 'OCP\\TextProcessing\\IManager' => __DIR__ . '/../../..' . '/lib/public/TextProcessing/IManager.php', 'OCP\\TextProcessing\\IProvider' => __DIR__ . '/../../..' . '/lib/public/TextProcessing/IProvider.php', + 'OCP\\TextProcessing\\IProviderWithExpectedRuntime' => __DIR__ . '/../../..' . '/lib/public/TextProcessing/IProviderWithExpectedRuntime.php', + 'OCP\\TextProcessing\\IProviderWithUserId' => __DIR__ . '/../../..' . '/lib/public/TextProcessing/IProviderWithUserId.php', 'OCP\\TextProcessing\\ITaskType' => __DIR__ . '/../../..' . '/lib/public/TextProcessing/ITaskType.php', 'OCP\\TextProcessing\\SummaryTaskType' => __DIR__ . '/../../..' . '/lib/public/TextProcessing/SummaryTaskType.php', 'OCP\\TextProcessing\\Task' => __DIR__ . '/../../..' . '/lib/public/TextProcessing/Task.php', @@ -1229,6 +1232,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OC\\Core\\Migrations\\Version28000Date20230728104802' => __DIR__ . '/../../..' . '/core/Migrations/Version28000Date20230728104802.php', 'OC\\Core\\Migrations\\Version28000Date20230803221055' => __DIR__ . '/../../..' . '/core/Migrations/Version28000Date20230803221055.php', 'OC\\Core\\Migrations\\Version28000Date20230906104802' => __DIR__ . '/../../..' . '/core/Migrations/Version28000Date20230906104802.php', + 'OC\\Core\\Migrations\\Version28000Date20231103104802' => __DIR__ . '/../../..' . '/core/Migrations/Version28000Date20231103104802.php', 'OC\\Core\\Notification\\CoreNotifier' => __DIR__ . '/../../..' . '/core/Notification/CoreNotifier.php', 'OC\\Core\\Service\\LoginFlowV2Service' => __DIR__ . '/../../..' . '/core/Service/LoginFlowV2Service.php', 'OC\\DB\\Adapter' => __DIR__ . '/../../..' . '/lib/private/DB/Adapter.php', diff --git a/lib/private/TextProcessing/Manager.php b/lib/private/TextProcessing/Manager.php index ee4fc70a06a..d1225b0f12f 100644 --- a/lib/private/TextProcessing/Manager.php +++ b/lib/private/TextProcessing/Manager.php @@ -29,7 +29,7 @@ use OC\AppFramework\Bootstrap\Coordinator; use OC\TextProcessing\Db\Task as DbTask; use OCP\IConfig; use OCP\TextProcessing\Exception\TaskFailureException; -use OCP\TextProcessing\IProvider2; +use OCP\TextProcessing\IProviderWithExpectedRuntime; use OCP\TextProcessing\Task; use OCP\TextProcessing\Task as OCPTask; use OC\TextProcessing\Db\TaskMapper; @@ -121,7 +121,7 @@ class Manager implements IManager { foreach ($providers as $provider) { try { $task->setStatus(OCPTask::STATUS_RUNNING); - if ($provider instanceof IProvider2) { + if ($provider instanceof IProviderWithExpectedRuntime) { $completionExpectedAt = new \DateTime('now'); $completionExpectedAt->add(new \DateInterval('PT'.$provider->getExpectedRuntime().'S')); $task->setCompletionExpectedAt($completionExpectedAt); @@ -159,7 +159,7 @@ class Manager implements IManager { } $task->setStatus(OCPTask::STATUS_SCHEDULED); [$provider, ] = $this->getPreferredProviders($task); - if ($provider instanceof IProvider2) { + if ($provider instanceof IProviderWithExpectedRuntime) { $completionExpectedAt = new \DateTime('now'); $completionExpectedAt->add(new \DateInterval('PT'.$provider->getExpectedRuntime().'S')); $task->setCompletionExpectedAt($completionExpectedAt); @@ -183,7 +183,7 @@ class Manager implements IManager { $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) { + if (!$provider instanceof IProviderWithExpectedRuntime || $provider->getExpectedRuntime() > $maxExecutionTime * 0.8) { $this->scheduleTask($task); return false; } diff --git a/lib/public/TextProcessing/IProvider2.php b/lib/public/TextProcessing/IProvider2.php deleted file mode 100644 index 74e6a47fed5..00000000000 --- a/lib/public/TextProcessing/IProvider2.php +++ /dev/null @@ -1,48 +0,0 @@ - - * - * @author Marcel Klehr - * - * @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 . - */ - - -namespace OCP\TextProcessing; - -/** - * This interface supersedes IProvider. It allows the system to learn - * the provider's expected runtime and lets the provider know which user is running a task - * @since 28.0.0 - * @template T of ITaskType - * @template-extends IProvider - */ -interface IProvider2 extends IProvider { - /** - * @param ?string $userId the current user's id - * @since 28.0.0 - */ - public function setUserId(?string $userId): string; - - /** - * @return int The expected average runtime of a task in seconds - * @since 28.0.0 - */ - public function getExpectedRuntime(): int; -} diff --git a/lib/public/TextProcessing/IProviderWithExpectedRuntime.php b/lib/public/TextProcessing/IProviderWithExpectedRuntime.php new file mode 100644 index 00000000000..6eb3dcc8cde --- /dev/null +++ b/lib/public/TextProcessing/IProviderWithExpectedRuntime.php @@ -0,0 +1,42 @@ + + * + * @author Marcel Klehr + * + * @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 . + */ + + +namespace OCP\TextProcessing; + +/** + * This interface allows the system to learn the provider's expected runtime + * @since 28.0.0 + * @template T of ITaskType + * @template-extends IProvider + */ +interface IProviderWithExpectedRuntime extends IProvider { + + /** + * @return int The expected average runtime of a task in seconds + * @since 28.0.0 + */ + public function getExpectedRuntime(): int; +} diff --git a/lib/public/TextProcessing/IProviderWithUserId.php b/lib/public/TextProcessing/IProviderWithUserId.php new file mode 100644 index 00000000000..e12317f52f7 --- /dev/null +++ b/lib/public/TextProcessing/IProviderWithUserId.php @@ -0,0 +1,41 @@ + + * + * @author Marcel Klehr + * + * @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 . + */ + + +namespace OCP\TextProcessing; + +/** + * This interface allows providers to access the user that initiated the task being run. + * @since 28.0.0 + * @template T of ITaskType + * @template-extends IProvider + */ +interface IProviderWithUserId extends IProvider { + /** + * @param ?string $userId the current user's id + * @since 28.0.0 + */ + public function setUserId(?string $userId): string; +} diff --git a/lib/public/TextProcessing/Task.php b/lib/public/TextProcessing/Task.php index f6b3a1a6a42..25b7132ee31 100644 --- a/lib/public/TextProcessing/Task.php +++ b/lib/public/TextProcessing/Task.php @@ -93,13 +93,13 @@ final class Task implements \JsonSerializable { /** * @psalm-param P $provider - * @param IProvider|IProvider2 $provider + * @param IProvider $provider * @return string * @since 27.1.0 */ - public function visitProvider(IProvider|IProvider2 $provider): string { + public function visitProvider(IProvider $provider): string { if ($this->canUseProvider($provider)) { - if ($provider instanceof IProvider2) { + if ($provider instanceof IProviderWithUserId) { $provider->setUserId($this->getUserId()); } return $provider->process($this->getInput()); -- cgit v1.2.3 From fe6d9e33b47dfc06e9e161971bd2b62532208fa5 Mon Sep 17 00:00:00 2001 From: Marcel Klehr Date: Wed, 29 Nov 2023 10:55:12 +0100 Subject: fix(TextProcessing): Make task type template param covariant Signed-off-by: Marcel Klehr --- lib/public/TextProcessing/IProvider.php | 2 +- lib/public/TextProcessing/Task.php | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) (limited to 'lib/public/TextProcessing/Task.php') diff --git a/lib/public/TextProcessing/IProvider.php b/lib/public/TextProcessing/IProvider.php index 6132e60b493..fc57add1835 100644 --- a/lib/public/TextProcessing/IProvider.php +++ b/lib/public/TextProcessing/IProvider.php @@ -31,7 +31,7 @@ use RuntimeException; /** * This is the interface that is implemented by apps that * implement a text processing provider - * @template T of ITaskType + * @psalm-template-covariant T of ITaskType * @since 27.1.0 */ interface IProvider { diff --git a/lib/public/TextProcessing/Task.php b/lib/public/TextProcessing/Task.php index 25b7132ee31..c62b7b2fff8 100644 --- a/lib/public/TextProcessing/Task.php +++ b/lib/public/TextProcessing/Task.php @@ -28,9 +28,7 @@ namespace OCP\TextProcessing; /** * This is a text processing task * @since 27.1.0 - * @psalm-template T of ITaskType - * @psalm-template S as class-string - * @psalm-template P as IProvider + * @psalm-template-covariant T of ITaskType */ final class Task implements \JsonSerializable { protected ?int $id = null; @@ -74,7 +72,7 @@ final class Task implements \JsonSerializable { protected int $status = self::STATUS_UNKNOWN; /** - * @psalm-param S $type + * @psalm-param class-string $type * @param string $type * @param string $input * @param string $appId @@ -92,7 +90,7 @@ final class Task implements \JsonSerializable { } /** - * @psalm-param P $provider + * @psalm-param IProvider $provider * @param IProvider $provider * @return string * @since 27.1.0 @@ -109,7 +107,7 @@ final class Task implements \JsonSerializable { } /** - * @psalm-param P $provider + * @psalm-param IProvider $provider * @param IProvider $provider * @return bool * @since 27.1.0 @@ -119,7 +117,7 @@ final class Task implements \JsonSerializable { } /** - * @psalm-return S + * @psalm-return class-string * @since 27.1.0 */ final public function getType(): string { @@ -207,7 +205,7 @@ final class Task implements \JsonSerializable { } /** - * @psalm-return array{id: ?int, type: S, status: 0|1|2|3|4, userId: ?string, appId: string, input: string, output: ?string, identifier: string, completionExpectedAt: ?int} + * @psalm-return array{id: ?int, type: class-string, status: 0|1|2|3|4, userId: ?string, appId: string, input: string, output: ?string, identifier: string, completionExpectedAt: ?int} * @since 27.1.0 */ public function jsonSerialize(): array { -- cgit v1.2.3