Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
82 changes: 55 additions & 27 deletions src/EntityContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

namespace Bottledcode\DurablePhp;

use Bottledcode\DurablePhp\Events\Event;
use Bottledcode\DurablePhp\Events\GiveOwnership;
use Bottledcode\DurablePhp\Events\RaiseEvent;
use Bottledcode\DurablePhp\Events\RevokeRole;
Expand All @@ -36,6 +37,7 @@
use Bottledcode\DurablePhp\Events\TaskCompleted;
use Bottledcode\DurablePhp\Events\WithDelay;
use Bottledcode\DurablePhp\Events\WithEntity;
use Bottledcode\DurablePhp\Events\WithFrom;
use Bottledcode\DurablePhp\Events\WithOrchestration;
use Bottledcode\DurablePhp\Exceptions\Unwind;
use Bottledcode\DurablePhp\Glue\Provenance;
Expand All @@ -59,6 +61,8 @@ class EntityContext implements EntityContextInterface
{
private static ?EntityContextInterface $current = null;

private readonly StateId $from;

public function __construct(
private readonly EntityId $id,
private readonly string $operation,
Expand All @@ -72,6 +76,7 @@ public function __construct(
private readonly Provenance $user,
) {
self::$current = $this;
$this->from = StateId::fromEntityId($this->id);
}

public static function current(): static
Expand Down Expand Up @@ -112,16 +117,23 @@ public function signalEntity(
array $input = [],
?DateTimeImmutable $scheduledTime = null,
): void {
$event = WithEntity::forInstance(
StateId::fromEntityId($entityId),
RaiseEvent::forOperation($operation, $input),
$event = $this->addFrom(
WithEntity::forInstance(
StateId::fromEntityId($entityId),
RaiseEvent::forOperation($operation, $input),
),
);
if ($scheduledTime) {
$event = WithDelay::forEvent($scheduledTime, $event);
}
$this->eventDispatcher->fire($event);
}

private function addFrom(Event $event): Event
{
return WithFrom::forEvent($this->from, $event);
}

public function getId(): EntityId
{
return $this->id;
Expand All @@ -140,9 +152,11 @@ public function startNewOrchestration(string $orchestration, array $input = [],

$instance = StateId::fromInstance(OrchestrationInstance($orchestration, $id));
$this->eventDispatcher->fire(
WithOrchestration::forInstance(
$instance,
StartExecution::asParent($input, []),
$this->addFrom(
WithOrchestration::forInstance(
$instance,
StartExecution::asParent($input, []),
),
),
);
}
Expand Down Expand Up @@ -184,9 +198,11 @@ public function delayUntil(
DateTimeInterface $until = new DateTimeImmutable(),
): void {
$this->eventDispatcher->fire(
WithDelay::forEvent(
$until,
WithEntity::forInstance(StateId::fromEntityId($this->id), RaiseEvent::forOperation($operation, $args)),
$this->addFrom(
WithDelay::forEvent(
$until,
WithEntity::forInstance(StateId::fromEntityId($this->id), RaiseEvent::forOperation($operation, $args)),
),
),
);
}
Expand All @@ -199,59 +215,71 @@ public function currentUserId(): string
public function shareOwnership(string $withUser): void
{
$this->eventDispatcher->fire(
WithEntity::forInstance(
StateId::fromEntityId($this->id),
ShareOwnership::withUser($withUser),
$this->addFrom(
WithEntity::forInstance(
StateId::fromEntityId($this->id),
ShareOwnership::withUser($withUser),
),
),
);
}

public function giveOwnership(string $withUser): void
{
$this->eventDispatcher->fire(
WithEntity::forInstance(
StateId::fromEntityId($this->id),
GiveOwnership::withUser($withUser),
$this->addFrom(
WithEntity::forInstance(
StateId::fromEntityId($this->id),
GiveOwnership::withUser($withUser),
),
),
);
}

public function grantUser(string $withUser, Operation ...$operation): void
{
$this->eventDispatcher->fire(
WithEntity::forInstance(
StateId::fromEntityId($this->id),
ShareWithUser::For($withUser, ...$operation),
$this->addFrom(
WithEntity::forInstance(
StateId::fromEntityId($this->id),
ShareWithUser::For($withUser, ...$operation),
),
),
);
}

public function grantRole(string $withRole, Operation ...$operation): void
{
$this->eventDispatcher->fire(
WithEntity::forInstance(
StateId::fromEntityId($this->id),
ShareWithRole::For($withRole, ...$operation),
$this->addFrom(
WithEntity::forInstance(
StateId::fromEntityId($this->id),
ShareWithRole::For($withRole, ...$operation),
),
),
);
}

public function revokeUser(string $user): void
{
$this->eventDispatcher->fire(
WithEntity::forInstance(
StateId::fromEntityId($this->id),
RevokeUser::completely($user),
$this->addFrom(
WithEntity::forInstance(
StateId::fromEntityId($this->id),
RevokeUser::completely($user),
),
),
);
}

public function revokeRole(string $role): void
{
$this->eventDispatcher->fire(
WithEntity::forInstance(
StateId::fromEntityId($this->id),
RevokeRole::completely($role),
$this->addFrom(
WithEntity::forInstance(
StateId::fromEntityId($this->id),
RevokeRole::completely($role),
),
),
);
}
Expand Down
16 changes: 13 additions & 3 deletions src/Events/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,26 @@
use Bottledcode\DurablePhp\MonotonicClock;
use Crell\fp\Evolvable;
use Crell\Serde\Attributes\ClassNameTypeMap;
use DateTimeImmutable;
use Ramsey\Uuid\Uuid;
use Stringable;

#[ClassNameTypeMap(key: 'eventType')]
abstract class Event implements \Stringable
abstract class Event implements Stringable
{
use Evolvable;

public \DateTimeImmutable $timestamp;
public DateTimeImmutable $timestamp;

public function __construct(public string $eventId)
public function __construct(public string $eventId {
set(string $value) {
if ($this instanceof HasInnerEventInterface && ($this->innerEvent ?? null)) {
$this->innerEvent->eventId = $value;
}
$this->eventId = $value;
}
get => $this->eventId;
})
{
$this->eventId = $this->eventId ?: Uuid::uuid7();
$this->timestamp = MonotonicClock::current()->now();
Expand Down
2 changes: 2 additions & 0 deletions src/Events/HasInnerEventInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,7 @@

interface HasInnerEventInterface
{
public Event $innerEvent { get; }

public function getInnerEvent(): Event;
}
2 changes: 1 addition & 1 deletion src/Events/RevokeUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public static function completely(string $userId): self
return new self($userId, null);
}

public function __toString()
public function __toString(): string
{
return sprintf('Revoke(user: %s)', $this->userId);
}
Expand Down
5 changes: 4 additions & 1 deletion src/Events/ShareOwnership.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@

namespace Bottledcode\DurablePhp\Events;

use Bottledcode\DurablePhp\Events\Shares\NeedsSource;
use Bottledcode\DurablePhp\Events\Shares\Operation;
use Ramsey\Uuid\Uuid;

#[NeedsSource(Operation::Owner)]
class ShareOwnership extends Event implements External
{
private function __construct(public string $userId)
Expand All @@ -38,7 +41,7 @@ public static function withUser(string $userId): self
return new self($userId);
}

public function __toString()
public function __toString(): string
{
return sprintf('ShareOwnership(%s)', $this->userId);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Events/ShareWithRole.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public static function For(string $role, Operation ...$allowedOperations): self
return new self($role, $allowedOperations);
}

public function __toString()
public function __toString(): string
{
return sprintf('Share(role: %s, %s)', $this->role, implode(', ', $this->allowedOperations));
}
Expand Down
2 changes: 1 addition & 1 deletion src/Events/ShareWithUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public static function For(string $userId, Operation ...$allowedOperations): sel
return new self($userId, $allowedOperations);
}

public function __toString()
public function __toString(): string
{
return sprintf('Share(user: %s, %s)', $this->userId, implode(', ', $this->allowedOperations));
}
Expand Down
2 changes: 1 addition & 1 deletion src/Events/WithActivity.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

class WithActivity extends Event implements HasInnerEventInterface, StateTargetInterface
{
public function __construct(string $eventId, public StateId $target, private readonly Event $innerEvent)
public function __construct(string $eventId, public StateId $target, public Event $innerEvent)
Comment thread
withinboredom marked this conversation as resolved.
{
parent::__construct($eventId);
}
Expand Down
6 changes: 3 additions & 3 deletions src/Events/WithDelay.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,17 @@

namespace Bottledcode\DurablePhp\Events;

use DateTimeImmutable;
use Ramsey\Uuid\Uuid;

class WithDelay extends Event implements HasInnerEventInterface
{
public function __construct(string $eventId, public \DateTimeImmutable $fireAt, public Event $innerEvent)
public function __construct(string $eventId, public DateTimeImmutable $fireAt, public Event $innerEvent)
{
parent::__construct($this->innerEvent ?: Uuid::uuid7());
}
Comment thread
withinboredom marked this conversation as resolved.

public static function forEvent(\DateTimeImmutable $fireAt, Event $innerEvent): static
public static function forEvent(DateTimeImmutable $fireAt, Event $innerEvent): static
{
return new static(
$innerEvent->eventId,
Expand All @@ -44,7 +45,6 @@ public static function forEvent(\DateTimeImmutable $fireAt, Event $innerEvent):

public function getInnerEvent(): Event
{
$this->innerEvent->eventId = $this->eventId;
return $this->innerEvent;
}

Expand Down
2 changes: 1 addition & 1 deletion src/Events/WithEntity.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

class WithEntity extends Event implements HasInnerEventInterface, StateTargetInterface
{
public function __construct(string $eventId, public StateId $target, private readonly Event $innerEvent)
public function __construct(string $eventId, public StateId $target, public Event $innerEvent)
Comment thread
withinboredom marked this conversation as resolved.
{
parent::__construct($eventId);
}
Expand Down
28 changes: 28 additions & 0 deletions src/Events/WithFrom.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Bottledcode\DurablePhp\Events;

use Bottledcode\DurablePhp\State\Ids\StateId;

class WithFrom extends Event implements HasInnerEventInterface
{
public function __construct(string $eventId, public StateId $from, public readonly Event $innerEvent)
{
parent::__construct($eventId);
}

public static function forEvent(StateId $from, Event $innerEvent): Event
{
return new self($innerEvent->eventId, $from, $innerEvent);
}

public function __toString(): string
{
return sprintf('WithFrom(%s, %s)', $this->from, $this->innerEvent);
}

public function getInnerEvent(): Event
{
return $this->innerEvent;
}
}
2 changes: 1 addition & 1 deletion src/Events/WithOrchestration.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class WithOrchestration extends Event implements HasInnerEventInterface, StateTa
public function __construct(
string $eventId,
public StateId $target,
private readonly Event $innerEvent,
public readonly Event $innerEvent,
) {
parent::__construct($this->innerEvent->eventId ?: Uuid::uuid7());
}
Expand Down
5 changes: 3 additions & 2 deletions src/Events/WithPriority.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

class WithPriority extends Event implements HasInnerEventInterface
{
private function __construct(public string $eventId, public int $priority, private Event $innerEvent)
private function __construct(public string $eventId, public int $priority, public Event $innerEvent)
Comment thread
withinboredom marked this conversation as resolved.
{
parent::__construct($this->eventId ?? Uuid::uuid7()->toString());
}
Expand Down Expand Up @@ -58,7 +58,8 @@ public function __toString(): string
return sprintf('WithPriority(%d, %s)', $this->priority, $this->innerEvent);
}

#[\Override] public function getInnerEvent(): Event
#[\Override]
public function getInnerEvent(): Event
{
return $this->innerEvent;
}
Expand Down
Loading