Skip to content
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
73 changes: 50 additions & 23 deletions src/EntityContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@
use Bottledcode\DurablePhp\Events\WithOrchestration;
use Bottledcode\DurablePhp\Exceptions\Unwind;
use Bottledcode\DurablePhp\Glue\Provenance;
use Bottledcode\DurablePhp\Proxy\SpyException;
use Bottledcode\DurablePhp\Proxy\SpyProxy;
use Bottledcode\DurablePhp\State\EntityHistory;
use Bottledcode\DurablePhp\State\EntityId;
use Bottledcode\DurablePhp\State\EntityState;
use Bottledcode\DurablePhp\State\Ids\StateId;
use Closure;
use Crell\Serde\Attributes\ClassSettings;
Expand Down Expand Up @@ -111,29 +113,6 @@ public function setState(mixed $value): void
$this->state = $value;
}

public function signalEntity(
EntityId $entityId,
string $operation,
array $input = [],
?DateTimeImmutable $scheduledTime = null,
): void {
$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 Down Expand Up @@ -161,6 +140,11 @@ public function startNewOrchestration(string $orchestration, array $input = [],
);
}

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

public function delay(Closure $self, DateTimeInterface $until = new DateTimeImmutable()): void
{
$classReflector = new ReflectionClass($this->history->getState());
Expand Down Expand Up @@ -283,4 +267,47 @@ public function revokeRole(string $role): void
),
);
}

public function signal(EntityId $entityId, callable $signal): void
{
$proxy = $this->spyProxy->define($entityId->name);
$operationName = null;
$arguments = null;
$proxy = new $proxy($operationName, $arguments);
try {
$proxy($signal);

if ($operationName === null || $arguments === null) {
return;
}
} catch (SpyException) {
$this->signalEntity($entityId, $operationName, $arguments ?? []);
}
}

public function signalEntity(
EntityId $entityId,
string $operation,
array $input = [],
?DateTimeImmutable $scheduledTime = null,
): void {
$event = $this->addFrom(
WithEntity::forInstance(
StateId::fromEntityId($entityId),
RaiseEvent::forOperation($operation, $input),
),
);
if ($scheduledTime) {
$event = WithDelay::forEvent($scheduledTime, $event);
}
$this->eventDispatcher->fire($event);
}

public function getSnapshot(EntityId $entityId): EntityState
{
$state = $this->eventDispatcher->getState(StateId::fromEntityId($entityId));
assert($state instanceof EntityHistory);

return $state->getState();
}
}
21 changes: 21 additions & 0 deletions src/EntityContextInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

use Bottledcode\DurablePhp\Events\Shares\Operation;
use Bottledcode\DurablePhp\State\EntityId;
use Bottledcode\DurablePhp\State\EntityState;
use Closure;
use Crell\Serde\Attributes\ClassNameTypeMap;
use DateTimeImmutable;
Expand Down Expand Up @@ -102,6 +103,26 @@ public function getId(): EntityId;
*/
public function getOperation(): string;

/**
* Call the entity with a single signal
*
* @template T of EntityState
*
* @param EntityId<T> $entityId
* @param callable(T): void $signal
*/
public function signal(EntityId $entityId, callable $signal): void;

/**
* Retrieve a snapshot of the remote entity state
*
* @template T of EntityState
*
* @param EntityId<T> $entityId
* @return EntityState<T>
*/
public function getSnapshot(EntityId $entityId): EntityState;

public function startNewOrchestration(string $orchestration, array $input = [], ?string $id = null): void;

public function delayUntil(
Expand Down
13 changes: 11 additions & 2 deletions src/Proxy/Generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,13 @@

abstract class Generator
{
public function __construct(protected string|null $cacheDir = null) {}
public function __construct(protected ?string $cacheDir = null) {}

/**
* Ensures that the given interface is implemented
*
* @throws \ReflectionException
*/
public function define(string $interface): string
{
$name = $this->getName($class = new ReflectionClass($interface));
Expand All @@ -45,14 +50,15 @@ public function define(string $interface): string
$cacheFile = $this->cacheDir . DIRECTORY_SEPARATOR . $name . '.php';
if (file_exists($cacheFile)) {
require_once $cacheFile;

return '\\' . $namespace . '\\' . $name;
}
}

$reflection = new ReflectionClass($interface);
$fullname = $this->getInterfaceNamespace($reflection) . '\\' . $this->getName($reflection);

if (!class_exists($fullname)) {
if (! class_exists($fullname)) {
eval($output = $this->generate($interface));
if ($cacheFile) {
file_put_contents($cacheFile, "<?php\n{$output}");
Expand Down Expand Up @@ -106,6 +112,7 @@ function (ReflectionMethod $method) {
$hooks[] = $this->pureMethod($hook, true);
}
$hooks[] = '}';

return implode(
"\n",
array_filter(
Expand All @@ -115,6 +122,7 @@ function (ReflectionMethod $method) {
);
}, $props);
$props = implode("\n", $props);

return <<<EOT
{$namespace}

Expand All @@ -139,6 +147,7 @@ protected function getTypes(ReflectionIntersectionType|ReflectionNamedType|Refle
if ($type->isBuiltin()) {
return $nullable . $type->getName();
}

return $nullable . '\\' . $type->getName();
}

Expand Down
5 changes: 4 additions & 1 deletion src/State/EntityId.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@
use Withinboredom\Record;

/**
* @template T
* @template T of EntityState
*/
readonly class EntityId extends Record implements Stringable
{
/**
* @var class-string<T>
*/
public protected(set) string $name;

public protected(set) string $id;
Expand Down