From 69e60b8c6e424a7fdd0c0ae0c7ec4f4c2bea1238 Mon Sep 17 00:00:00 2001 From: Matthias Neid Date: Fri, 27 Oct 2023 17:30:32 +0200 Subject: [PATCH] added special sync handling function for tasks --- README.md | 8 ++++++++ src/Environment/Sync/SyncRuntime.php | 10 ++++++++++ src/Task/Task.php | 24 ++++++++++++++++++++++++ src/Task/TaskInterface.php | 11 +++++++++++ test/Integration/AsyncWorkerTestCase.php | 9 +++++++++ test/Integration/SyncWorkerTest.php | 9 +++++++++ test/Util/Task/SyncTask.php | 18 ++++++++++++++++++ 7 files changed, 89 insertions(+) create mode 100644 test/Util/Task/SyncTask.php diff --git a/README.md b/README.md index 9ef6fe0..aaa0ed3 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ Tasks can communicate back to the main process during execution and handle resul * [Child/parent attributes](#childparent-attributes) * [Synchronized properties](#synchronized-properties) * [Serialization in other classes](#serialization-in-other-classes) + * [Synchronous environment](#synchronous-environment) * [Handling the result](#handling-the-result) * [Timeout](#timeout) * [Handling errors](#handling-errors) @@ -229,6 +230,13 @@ When using only the [`NotSerializable`](src/Communication/Serialization/NotSeria When using both attributes, all properties **must** be marked with either the [`Serializable`](src/Communication/Serialization/Serializable.php) or [`NotSerializable`](src/Communication/Serialization/NotSerializable.php) attribute, otherwise an exception will be thrown. +### Synchronous environment + +In some cases special handling is required when the task is executed in a synchronous environment +using the [`SyncWorker`](src/Environment/Sync/SyncWorker.php), e.g. you might not want to close +file handles that are still used by other tasks. The `Task::isSync()` function can +be used to check if the task is being executed synchronously. + ### Handling the result The `Task::handleResult()` function is called when the task returns a value. It can be used to handle diff --git a/src/Environment/Sync/SyncRuntime.php b/src/Environment/Sync/SyncRuntime.php index e57ae81..c2248d2 100644 --- a/src/Environment/Sync/SyncRuntime.php +++ b/src/Environment/Sync/SyncRuntime.php @@ -3,6 +3,7 @@ namespace Aternos\Taskmaster\Environment\Sync; use Aternos\Taskmaster\Communication\Promise\ResponsePromise; +use Aternos\Taskmaster\Communication\Request\RunTaskRequest; use Aternos\Taskmaster\Communication\RequestInterface; use Aternos\Taskmaster\Communication\ResponseInterface; use Aternos\Taskmaster\Runtime\Runtime; @@ -51,6 +52,15 @@ public function sendRequest(RequestInterface $request): ResponsePromise return (new ResponsePromise())->resolve($response); } + /** + * @inheritDoc + */ + protected function runTask(RunTaskRequest $request): ResponseInterface + { + $request->getTask()->setSync(); + return parent::runTask($request); + } + /** * @inheritDoc */ diff --git a/src/Task/Task.php b/src/Task/Task.php index ab4f673..0d1ea71 100644 --- a/src/Task/Task.php +++ b/src/Task/Task.php @@ -35,6 +35,7 @@ abstract class Task implements TaskInterface #[OnParent] protected ?Exception $error = null; #[OnParent] protected ?TaskPromise $promise = null; #[OnParent] protected ?float $timeout = null; + #[OnChild] protected bool $sync = false; /** * @inheritDoc @@ -263,4 +264,27 @@ public function setTimeout(?float $timeout): static $this->timeout = $timeout; return $this; } + + /** + * @inheritDoc + */ + public function setSync(bool $sync = true): static + { + $this->sync = $sync; + return $this; + } + + /** + * Check if the task is executed in a sync environment + * + * Some cases must be handled differently in a sync environment because + * you are operating on the same and not just equal objects, e.g. you + * might not want to close file handles that are still used by other tasks. + * + * @return bool + */ + protected function isSync(): bool + { + return $this->sync; + } } \ No newline at end of file diff --git a/src/Task/TaskInterface.php b/src/Task/TaskInterface.php index 76f59d3..661f364 100644 --- a/src/Task/TaskInterface.php +++ b/src/Task/TaskInterface.php @@ -154,4 +154,15 @@ public function getTimeout(): ?float; * @return $this */ public function setTimeout(?float $timeout): static; + + /** + * Tell the task that it's being executed in a sync environment + * + * Some cases must be handled differently in a sync environment because + * you are operating on the same and not just equal objects, e.g. you + * might not want to close file handles that are still used by other tasks. + * + * @return $this + */ + public function setSync(bool $sync = true): static; } \ No newline at end of file diff --git a/test/Integration/AsyncWorkerTestCase.php b/test/Integration/AsyncWorkerTestCase.php index 7599663..25981ae 100644 --- a/test/Integration/AsyncWorkerTestCase.php +++ b/test/Integration/AsyncWorkerTestCase.php @@ -8,6 +8,7 @@ use Aternos\Taskmaster\Test\Util\Task\EmptyTask; use Aternos\Taskmaster\Test\Util\Task\InterruptableSleepTask; use Aternos\Taskmaster\Test\Util\Task\SleepTask; +use Aternos\Taskmaster\Test\Util\Task\SyncTask; use Aternos\Taskmaster\Test\Util\Task\WarningTask; use Aternos\Taskmaster\Worker\WorkerInterface; @@ -56,6 +57,14 @@ public function testDefaultTimeout(): void } } + public function testSyncTask(): void + { + $task = new SyncTask(); + $this->taskmaster->runTask($task); + $this->taskmaster->wait(); + $this->assertFalse($task->getResult()); + } + public function testRecoverAfterTimeout(): void { $this->taskmaster->setDefaultTaskTimeout(0.005 * $this->getTimeFactor()); diff --git a/test/Integration/SyncWorkerTest.php b/test/Integration/SyncWorkerTest.php index fd6194f..e1a77f4 100644 --- a/test/Integration/SyncWorkerTest.php +++ b/test/Integration/SyncWorkerTest.php @@ -4,6 +4,7 @@ use Aternos\Taskmaster\Environment\Sync\SyncWorker; use Aternos\Taskmaster\Taskmaster; +use Aternos\Taskmaster\Test\Util\Task\SyncTask; class SyncWorkerTest extends WorkerTestCase { @@ -12,4 +13,12 @@ protected function createTaskmaster(): void $this->taskmaster = new Taskmaster(); $this->taskmaster->addWorker(new SyncWorker()); } + + public function testSyncTask(): void + { + $task = new SyncTask(); + $this->taskmaster->runTask($task); + $this->taskmaster->wait(); + $this->assertTrue($task->getResult()); + } } \ No newline at end of file diff --git a/test/Util/Task/SyncTask.php b/test/Util/Task/SyncTask.php new file mode 100644 index 0000000..bc8a42a --- /dev/null +++ b/test/Util/Task/SyncTask.php @@ -0,0 +1,18 @@ +isSync(); + } +} \ No newline at end of file