From af60e61c5c2d6e7798c88842be2a1403bf3e6986 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=91=E6=9E=97?= Date: Tue, 11 Oct 2022 17:33:00 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=98=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kiri-actor/Actor.php | 61 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/kiri-actor/Actor.php b/kiri-actor/Actor.php index dd687651..3b6b8463 100644 --- a/kiri-actor/Actor.php +++ b/kiri-actor/Actor.php @@ -22,6 +22,12 @@ abstract class Actor implements ActorInterface, JsonSerializable private bool $isShutdown = false; + /** + * @var int + */ + private int $messageId = -1; + + /** * @var int */ @@ -40,6 +46,12 @@ abstract class Actor implements ActorInterface, JsonSerializable private float $startTime = 0; + /** + * @var int + */ + private int $refreshInterval = 0; + + /** * @return ActorState */ @@ -77,7 +89,6 @@ abstract class Actor implements ActorInterface, JsonSerializable } - /** * @return void */ @@ -87,6 +98,15 @@ abstract class Actor implements ActorInterface, JsonSerializable } + /** + * @return bool + */ + public function isShutdown(): bool + { + return $this->isShutdown; + } + + /** * @param $id * @return static @@ -136,10 +156,20 @@ abstract class Actor implements ActorInterface, JsonSerializable public function shutdown(): void { $this->isShutdown = true; + Coroutine::cancel($this->coroutineId); + if ($this->messageId > -1) { + Coroutine::cancel($this->messageId); + } $this->channel->close(); } + /** + * @return void + */ + abstract public function onUpdate(): void; + + /** * @return void */ @@ -147,21 +177,44 @@ abstract class Actor implements ActorInterface, JsonSerializable { $this->setState(ActorState::BUSY); $this->init(); - $this->loop(); + $this->messageId = Coroutine::create(fn() => $this->loop()); + $this->interval(); $this->setState(ActorState::IDLE); } /** - * @return mixed + * @return void */ - private function loop(): mixed + private function interval(): void { + if ($this->isShutdown()) { + return; + } + $this->onUpdate(); + + Coroutine::sleep($this->refreshInterval / 1000); + + $this->interval(); + } + + + /** + * @return bool + */ + private function loop(): bool + { + if ($this->messageId == -1) { + $this->messageId = Coroutine::getCid(); + } if ($this->channel->errCode == SWOOLE_CHANNEL_CLOSED) { $this->channel = new Channel(99); } $message = $this->channel->pop(); $this->process($message); + if ($this->isShutdown()) { + return true; + } return $this->loop(); }