Skip to content
26 changes: 14 additions & 12 deletions composer.lock

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

13 changes: 10 additions & 3 deletions src/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
define('STORE', 'statestore');

use Dapr\Actors\ActorProxy;
use Dapr\Actors\ActorReference;
use Dapr\Actors\Generators\ProxyFactory;
use Dapr\Actors\IActor;
use Dapr\Actors\Reminder;
use Dapr\Actors\Timer;
Expand Down Expand Up @@ -58,13 +60,14 @@ public function increment(int $amount = 1): void

$app->get(
'/test/actors',
function (ActorProxy $actorProxy, DaprClient $client, LoggerInterface $logger) {
$id = uniqid(prefix: 'actor_');
function (ProxyFactory $proxyFactory, DaprClient $client, LoggerInterface $logger) {
$id = uniqid(prefix: 'actor_');
$reference = new ActorReference($id, 'SimpleActor');

/**
* @var ISimpleActor|IActor $actor
*/
$actor = $actorProxy->get(ISimpleActor::class, $id);
$actor = $reference->bind(ISimpleActor::class, $proxyFactory);
$body = [];

$logger->critical('Created actor proxy');
Expand All @@ -73,6 +76,10 @@ function (ActorProxy $actorProxy, DaprClient $client, LoggerInterface $logger) {
$body = assert_equals($body, 1, $actor->get_count(), 'Actor should have data');
$logger->critical('Incremented actor');

// get the actor proxy again
$reference = ActorReference::get($actor);
$actor = $reference->bind(ISimpleActor::class, $proxyFactory);

$reminder = new Reminder(
name: 'increment',
due_time: new DateInterval('PT1S'),
Expand Down
7 changes: 4 additions & 3 deletions src/lib/Actors/ActorProxy.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Dapr\Actors\Generators\ProxyFactory;
use DI\DependencyException;
use DI\NotFoundException;
use JetBrains\PhpStorm\Deprecated;
use LogicException;
use Psr\Log\LoggerInterface;
use ReflectionClass;
Expand All @@ -29,15 +30,15 @@ public function __construct(protected ProxyFactory $proxyFactory, protected Logg
* Returns an actor proxy
*
* @param string $interface
* @param mixed $id The id to proxy for
* @param string $id
* @param string|null $override_type Allow overriding the Dapr type for a given interface
*
* @return object
* @throws ReflectionException
* @throws DependencyException
* @throws NotFoundException
* @throws ReflectionException
*/
public function get(string $interface, mixed $id, string|null $override_type = null): object
public function get(string $interface, string $id, string|null $override_type = null): object
{
$this->logger?->debug('Getting actor proxy for {i}||{id}', ['i' => $interface, 'id' => $id]);

Expand Down
98 changes: 98 additions & 0 deletions src/lib/Actors/ActorReference.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php

namespace Dapr\Actors;

use Dapr\Actors\Attributes\DaprType;
use Dapr\Actors\Generators\ProxyFactory;
use Dapr\Deserialization\Deserializers\IDeserialize;
use Dapr\Deserialization\IDeserializer;
use Dapr\Serialization\ISerializer;
use Dapr\Serialization\Serializers\ISerialize;
use LogicException;
use ReflectionClass;

/**
* Class ActorReference
* @package Dapr\Actors
*/
final class ActorReference implements IActorReference, ISerialize, IDeserialize
{
public function __construct(private string $id, private string $actor_type)
{
}

/**
* @inheritDoc
*/
public static function get(mixed $actor): IActorReference
{
$id = $actor?->get_id();

if ($id === null) {
throw new LogicException('actor(proxy) must implement get_id()');
}

$detected_dapr_type = self::get_dapr_type($actor);

$dapr_type = $actor->DAPR_TYPE ?? $detected_dapr_type?->type;

if ($dapr_type === null) {
throw new LogicException('Missing DaprType attribute on '.$actor::class);
}

return new self(id: $id, actor_type: $dapr_type);
}

private static function get_dapr_type(object|string $type): DaprType|null
{
$reflector = new ReflectionClass($type);
/**
* @var DaprType|null $type_attribute
*/
$type_attribute = ($reflector->getAttributes(DaprType::class)[0] ?? null)?->newInstance();

return $type_attribute;
}

public static function deserialize(mixed $value, IDeserializer $deserializer): mixed
{
return new ActorReference(id: $value['ActorId'], actor_type: $value['ActorType']);
}

/**
* @inheritDoc
*/
public function bind(string $interface, ProxyFactory $proxy_factory): mixed
{
return $proxy_factory->get_generator($interface, $this->actor_type)->get_proxy(
$this->id
);
}

/**
* @inheritDoc
*/
public function get_actor_id(): string
{
return $this->id;
}

/**
* @inheritDoc
*/
public function get_actor_type(): string
{
return $this->actor_type;
}

/**
* @param ActorReference $value
* @param ISerializer $serializer
*
* @return array
*/
public function serialize(mixed $value, ISerializer $serializer): array
{
return ['ActorId' => $value->id, 'ActorType' => $value->actor_type];
}
}
7 changes: 3 additions & 4 deletions src/lib/Actors/ActorRuntime.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace Dapr\Actors;

use Dapr\Actors\Internal\Caches\CacheInterface;
use Dapr\Actors\Internal\Caches\FileCache;
use Dapr\Actors\Internal\Caches\NoCache;
use Dapr\Deserialization\IDeserializer;
Expand All @@ -14,7 +13,6 @@
use DI\FactoryInterface;
use DI\NotFoundException;
use Exception;
use JetBrains\PhpStorm\ArrayShape;
use Psr\Log\LoggerInterface;
use ReflectionClass;
use ReflectionException;
Expand Down Expand Up @@ -69,7 +67,7 @@ public function do_method(IActor $actor, string $method, mixed $arg): mixed

public function deactivate_actor(IActor $actor, string $dapr_type): void
{
$id = $actor->get_id();
$id = $actor->get_id();
$activation_tracker = hash('sha256', $dapr_type.$id);
$activation_tracker = rtrim(
sys_get_temp_dir(),
Expand Down Expand Up @@ -247,7 +245,8 @@ protected function begin_transaction(
*/
protected function get_actor(ReflectionClass $reflection, string $dapr_type, string $id, array $states): IActor
{
$states['id'] = $id;
$states['id'] = $id;
$this->container->set(ActorReference::class, new ActorReference($id, $dapr_type));
$actor = $this->factory->make($reflection->getName(), $states);
$activation_tracker = hash('sha256', $dapr_type.$id);
$activation_tracker = rtrim(
Expand Down
41 changes: 41 additions & 0 deletions src/lib/Actors/IActorReference.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace Dapr\Actors;

use Dapr\Actors\Generators\ProxyFactory;

/**
* Class IActorReference
* @package Dapr\Actors
*/
interface IActorReference
{
/**
* Get a reference from a given actor that implements IActor
*
* @param IActor $actor The actor or actor interface to extract the reference from
*
* @return IActorReference The actor's reference
*/
public static function get(mixed $actor): IActorReference;

/**
* Get an actor reference bound to a given interface.
*
* @param string $interface The interface of the actor
* @param ProxyFactory $proxy_factory The proxy factory to use
*
* @return IActor The actor's reference
*/
public function bind(string $interface, ProxyFactory $proxy_factory): mixed;

/**
* @return string The actor id
*/
public function get_actor_id(): string;

/**
* @return string The actor type
*/
public function get_actor_type(): string;
}
Loading