Skip to content

Commit

Permalink
allow using closures to signal things
Browse files Browse the repository at this point in the history
  • Loading branch information
withinboredom committed Oct 29, 2023
1 parent a812116 commit b415f0f
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 9 deletions.
1 change: 0 additions & 1 deletion .idea/durable-php.iml

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

10 changes: 8 additions & 2 deletions src/DurableClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@

class DurableClient implements DurableClientInterface
{
public function __construct(private EntityClientInterface $entityClient, private OrchestrationClientInterface $orchestrationClient)
{
public function __construct(
private EntityClientInterface $entityClient, private OrchestrationClientInterface $orchestrationClient
) {
}

public function cleanEntityStorage(): void
Expand Down Expand Up @@ -109,4 +110,9 @@ public function getEntitySnapshot(EntityId $entityId): EntityState|null
{
return $this->entityClient->getEntitySnapshot($entityId);
}

public function signal(EntityId|string $entityId, \Closure $signal): void
{
$this->entityClient->signal($entityId, $signal);
}
}
25 changes: 19 additions & 6 deletions src/EntityClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
use Bottledcode\DurablePhp\Events\RaiseEvent;
use Bottledcode\DurablePhp\Events\WithDelay;
use Bottledcode\DurablePhp\Events\WithEntity;
use Bottledcode\DurablePhp\Proxy\SpyProxy;
use Bottledcode\DurablePhp\State\EntityHistory;
use Bottledcode\DurablePhp\State\EntityId;
use Bottledcode\DurablePhp\State\EntityState;
Expand All @@ -40,7 +41,7 @@ class EntityClient implements EntityClientInterface
use PartitionCalculator;


public function __construct(private Config $config, private Source $source)
public function __construct(private Config $config, private Source $source, private SpyProxy $spyProxy)
{
}

Expand All @@ -54,6 +55,23 @@ public function listEntities(): \Generator
throw new \Exception('Not implemented');
}

public function getEntitySnapshot(EntityId $entityId): EntityState|null
{
return $this->source->get(StateId::fromEntityId($entityId), EntityHistory::class)?->getState();
}

public function signal(EntityId|string $entityId, \Closure $signal): void
{
$interfaceReflector = new \ReflectionFunction($signal);
$interfaceName = $interfaceReflector->getParameters()[0]->getName();
$spy = $this->spyProxy->define($interfaceName);
$class = new $spy($operationName, $arguments);
$signal($class);
$this->signalEntity(
is_string($entityId) ? new EntityId($interfaceName, $entityId) : $entityId, $operationName, $arguments
);
}

public function signalEntity(
EntityId $entityId,
string $operationName,
Expand All @@ -70,9 +88,4 @@ public function signalEntity(

$this->source->storeEvent($event, false);
}

public function getEntitySnapshot(EntityId $entityId): EntityState|null
{
return $this->source->get(StateId::fromEntityId($entityId), EntityHistory::class)?->getState();
}
}
9 changes: 9 additions & 0 deletions src/EntityClientInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@ public function signalEntity(
\DateTimeImmutable $scheduledTime = null
): void;

/**
* Signals an entity using a closure
*
* @param EntityId|string $entityId The id of the entity to signal
* @param \Closure $signal
* @return void
*/
public function signal(EntityId|string $entityId, \Closure $signal): void;

/**
* @template T
* @param EntityId $entityId
Expand Down
77 changes: 77 additions & 0 deletions src/Proxy/SpyProxy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php
/*
* Copyright ©2023 Robert Landers
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the “Software”), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
* OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

namespace Bottledcode\DurablePhp\Proxy;

class SpyProxy extends Generator
{
protected function pureMethod(\ReflectionMethod $method): string
{
return $this->impureCall($method);
}

protected function impureCall(\ReflectionMethod $method): string
{
$name = $method->getName();
$params = $method->getParameters();
$params = array_map(
function (\ReflectionParameter $param) {
$type = $param->getType();
if ($type !== null) {
$type = $this->getTypes($type);
}

return "$type \${$param->getName()}";
},
$params
);
$params = implode(', ', $params);
$return = $method->getReturnType();
$return = $return ? ": {$this->getTypes($return)}" : '';

return <<<EOT
public function $name($params)$return {
\$this->operation = __METHOD__;
\$this->arguments = func_get_args();
throw new \Exception('Not implemented');
}
EOT;
}

protected function getName(\ReflectionClass $class): string
{
return "__SpyProxy_{$class->getShortName()}";
}

protected function impureSignal(\ReflectionMethod $method): string
{
return $this->impureCall($method);
}

protected function preamble(\ReflectionClass $class): string
{
return <<<'EOT'
public function __construct(private string|null &$operation = null, private array|null &$arguments = null) {}
EOT;
}
}

0 comments on commit b415f0f

Please sign in to comment.