ヒエラルキー構造を利用してみよう
次にアクターモデルの特徴であるヒエラルキー構造を利用してみましょう。
HelloActorを親アクターとして、WorldActorを子アクターとして生成し、WorldActorにHelloResponseメッセージに関する処理を担当してもらうようにします。
次のようなWorldActorクラスを作成します。
<?php
declare(strict_types=1);
namespace Sample;
use Phluxor\ActorSystem\Context\ContextInterface;
use Phluxor\ActorSystem\Message\ActorInterface;
class WorldActor implements ActorInterface
{
public function receive(ContextInterface $context): void
{
$message = $context->message();
if ($message instanceof Message\HelloRequest) {
$response = new Message\HelloResponse('Hello Child, ' . $message->message);
$context->respond($response);
}
}
}
WorldActorはHelloRequestメッセージを受信した場合にHelloResponseメッセージを作成し、送信元に返信する処理を行います。
次にHelloActorを親アクターとしてWorldActorを生成するように変更します。
<?php
declare(strict_types=1);
namespace Sample;
use Phluxor\ActorSystem\Context\ContextInterface;
use Phluxor\ActorSystem\Message\ActorInterface;
use Phluxor\ActorSystem\Props;
use Phluxor\ActorSystem\Ref;
class HelloActor implements ActorInterface
{
private ?Ref $sender = null;
public function receive(ContextInterface $context): void
{
$message = $context->message();
switch (true) {
case $message instanceof Message\HelloRequest:
$this->sender = $context->sender();
$ref = $context->spawn(
Props::fromProducer(fn() => new WorldActor())
);
$context->request($ref, $message);
break;
case $message instanceof Message\HelloResponse:
$context->send($this->sender, $message);
break;
}
}
}
HelloActorはHelloRequestメッセージを受信した場合に、子アクターとしてWorldActorを生成しHelloRequestメッセージを送信します。
子アクターであるWorldActorでHelloResponseメッセージを作成し、HelloActorに返信するように変更したので、HelloResponseメッセージを受信した場合には送信元にHelloResponseメッセージを送信します。
このときアクターのヒエラルキー構造は次のようになります。

これまでのコード例の場合は実際には$1/$3のような形でヒエラルキー構造を持ち、名前は自動で生成されますが、spawnNamedメソッドを利用することで図と同一のアクター構造を生成することも可能です。
その場合はユニークな名前を指定することが必須となりますので、名前の重複に注意して利用するようにしてください。
アクターのコンテキストには誰からメッセージが送信されたかが含まれています。
このヒエラルキー構造からわかるように、HelloActorはWorldActorやFutureからメッセージを受信していますので、最初に送られてきたSenderの情報を保持しておくことで、HelloResponseメッセージを送信元に返信できます。
アクターは状態を共有することはありませんので、このようにアクター毎に情報を保持できます。
なおrespondは直前の送信元に返信するためのメソッドのため、ここではsendメソッドを利用して送信先を指定し返信を行っています。
このコードをコンソールなどから実行すると下記のように表示されます。

