Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

task finally #42

Merged
merged 5 commits into from
Dec 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 25 additions & 25 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions src/EntityFinally.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace kuaukutsu\poc\task;

use kuaukutsu\poc\task\state\TaskStateInterface;

interface EntityFinally
{
/**
* @param non-empty-string $uuid Task UUID
*/
public function handle(string $uuid, TaskStateInterface $state): void;
}
21 changes: 21 additions & 0 deletions src/TaskDraft.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace kuaukutsu\poc\task;

use LogicException;
use kuaukutsu\poc\task\dto\TaskOptions;
use kuaukutsu\poc\task\state\TaskFlagCommand;
use kuaukutsu\poc\task\state\TaskStateInterface;
Expand All @@ -15,6 +16,11 @@ final class TaskDraft implements EntityTask

private float $timeout = 300.;

/**
* @var class-string<EntityFinally>|null
*/
private ?string $finally = null;

private TaskStateInterface $state;

private readonly EntityUuid $uuid;
Expand Down Expand Up @@ -49,6 +55,7 @@ public function getOptions(): TaskOptions
{
return new TaskOptions(
timeout: $this->timeout,
finally: $this->finally,
);
}

Expand Down Expand Up @@ -88,4 +95,18 @@ public function setTimeout(float $timeout): self
$this->timeout = max(1, $timeout);
return $this;
}

/**
* @param class-string<EntityFinally> $handler
* @throws LogicException not implement the EntityFinally
*/
public function setFinally(string $handler): self
{
if (is_a($handler, EntityFinally::class, true) === false) {
throw new LogicException("[$handler] must implement the EntityFinally.");
}

$this->finally = $handler;
return $this;
}
}
8 changes: 7 additions & 1 deletion src/dto/TaskOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,20 @@
namespace kuaukutsu\poc\task\dto;

use kuaukutsu\poc\task\EntityArrable;
use kuaukutsu\poc\task\EntityFinally;

/**
* @readonly
*/
final class TaskOptions implements EntityArrable
{
/**
* @param float $timeout В секундах.
* @param class-string<EntityFinally>|null $finally
*/
public function __construct(
public float $timeout,
public readonly float $timeout,
public readonly ?string $finally = null,
) {
}

Expand Down
54 changes: 54 additions & 0 deletions src/handler/TaskFinallyHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

namespace kuaukutsu\poc\task\handler;

use Throwable;
use DI\DependencyException;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Container\ContainerInterface;
use kuaukutsu\poc\task\dto\TaskOptions;
use kuaukutsu\poc\task\state\TaskStateInterface;
use kuaukutsu\poc\task\state\TaskStatePrepare;
use kuaukutsu\poc\task\EntityFinally;

final class TaskFinallyHandler
{
use TaskStatePrepare;

public function __construct(private readonly ContainerInterface $container)
{
}

/**
* @param non-empty-string $uuid Task UUID
*/
public function handle(string $uuid, TaskOptions $options, TaskStateInterface $state): void
{
if ($options->finally === null) {
return;
}

try {
$this->factory($options->finally)->handle($uuid, $state);
} catch (Throwable) {
}
}

/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
private function factory(string $className): EntityFinally
{
/** @var EntityFinally|object $handler */
$handler = $this->container->get($className);
if ($handler instanceof EntityFinally) {
return $handler;
}

throw new DependencyException("[$className] must implement EntityFinally.");
}
}
8 changes: 8 additions & 0 deletions src/processing/TaskHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use kuaukutsu\poc\task\handler\StageContextFactory;
use kuaukutsu\poc\task\handler\StageExecutor;
use kuaukutsu\poc\task\handler\TaskFactory;
use kuaukutsu\poc\task\handler\TaskFinallyHandler;
use kuaukutsu\poc\task\service\StageCommand;
use kuaukutsu\poc\task\service\StageQuery;
use kuaukutsu\poc\task\service\TaskExecutor;
Expand All @@ -29,6 +30,7 @@ public function __construct(
private readonly TaskQuery $taskQuery,
private readonly TaskFactory $taskFactory,
private readonly TaskExecutor $taskExecutor,
private readonly TaskFinallyHandler $finallyHandler,
private readonly StageQuery $stageQuery,
private readonly StageCommand $stageCommand,
private readonly StageContextFactory $contextFactory,
Expand Down Expand Up @@ -107,6 +109,12 @@ public function complete(string $taskUuid, string $stageUuid): TaskStateInterfac
return $stateRelation;
}

$this->finallyHandler->handle(
$task->getUuid(),
$task->getOptions(),
$state,
);

return $state;
}

Expand Down
34 changes: 34 additions & 0 deletions tests/TaskBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
use kuaukutsu\poc\task\TaskBuilder;
use kuaukutsu\poc\task\tests\stub\IncreaseNumberStageStub;
use kuaukutsu\poc\task\tests\stub\TestStageStub;
use kuaukutsu\poc\task\tests\stub\TestFinally;
use kuaukutsu\poc\task\tests\stub\TestResponse;

final class TaskBuilderTest extends TestCase
{
Expand Down Expand Up @@ -209,6 +211,38 @@ class: TestStageStub::class,
$this->builder->build($draftDuplicate);
}

public function testCreateFinally(): void
{
$draft = $this->builder->create(
'finaly',
new EntityWrapper(
class: TestStageStub::class,
params: [
'name' => 'Test initialization.',
],
),
);

$draft->setFinally(TestFinally::class);
self::assertEquals(TestFinally::class, $draft->getOptions()->finally);
}

public function testCreateFinallyException(): void
{
$draft = $this->builder->create(
'finaly',
new EntityWrapper(
class: TestStageStub::class,
params: [
'name' => 'Test initialization.',
],
),
);

$this->expectException(LogicException::class);
$draft->setFinally(TestResponse::class);
}

protected function tearDown(): void
{
if ($this->task !== null) {
Expand Down
Loading