2024-03-10 03:06:19 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace NoccyLabs\Mercureact\Broker;
|
|
|
|
|
|
|
|
use SplObjectStorage;
|
|
|
|
|
|
|
|
class TopicManager
|
|
|
|
{
|
|
|
|
/** @var array<string,Topic> */
|
|
|
|
private array $topics = [];
|
|
|
|
|
2024-03-10 23:06:00 +01:00
|
|
|
private SplObjectStorage $subscribers;
|
|
|
|
|
|
|
|
public function __construct()
|
|
|
|
{
|
|
|
|
$this->subscribers = new SplObjectStorage();
|
|
|
|
}
|
2024-03-10 03:06:19 +01:00
|
|
|
|
|
|
|
public function getTopic(string $topic): Topic
|
|
|
|
{
|
|
|
|
if (!isset($this->topics[$topic])) {
|
|
|
|
$this->topics[$topic] = new Topic($topic);
|
|
|
|
}
|
|
|
|
return $this->topics[$topic];
|
|
|
|
}
|
|
|
|
|
|
|
|
public function publish(Message $message): void
|
|
|
|
{
|
|
|
|
foreach ($message->topic as $topic) {
|
|
|
|
$this->getTopic($topic)->publish($message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-10 23:06:00 +01:00
|
|
|
public function subscribe(SubscriberInterface $subscriber, array $topics): void
|
|
|
|
{
|
|
|
|
foreach ($topics as $topic) {
|
2024-03-10 23:12:34 +01:00
|
|
|
if ($subscriber->isAuthorized($topic))
|
|
|
|
$this->getTopic($topic)->addSubscriber($subscriber);
|
2024-03-10 23:06:00 +01:00
|
|
|
}
|
2024-03-10 23:12:34 +01:00
|
|
|
$this->subscribers->attach($subscriber);
|
2024-03-10 23:06:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function unsubscribe(SubscriberInterface $subscriber, ?array $topics=null): void
|
|
|
|
{
|
|
|
|
if (!$topics) {
|
|
|
|
foreach ($this->topics as $topic) {
|
|
|
|
$topic->removeSubscriber($subscriber);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
foreach ($topics as $topic) {
|
|
|
|
$this->getTopic($topic)->removeSubscriber($subscriber);
|
|
|
|
}
|
2024-03-10 23:12:34 +01:00
|
|
|
$this->subscribers->detach($subscriber);
|
2024-03-10 23:06:00 +01:00
|
|
|
}
|
|
|
|
|
2024-03-10 03:06:19 +01:00
|
|
|
public function getTopicCount(): int
|
|
|
|
{
|
|
|
|
return count($this->topics);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getSubscriberCount(): int
|
|
|
|
{
|
2024-03-10 23:06:00 +01:00
|
|
|
return count($this->subscribers);
|
2024-03-10 03:06:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function garbageCollect(): void
|
|
|
|
{
|
|
|
|
$this->topics = array_filter(
|
|
|
|
$this->topics,
|
|
|
|
function (Topic $topic) {
|
|
|
|
$topic->garbageCollect();
|
|
|
|
return ($topic->getHistorySize() > 0 && $topic->getSubscriberCount() > 0) || ($topic->getAge() < 60);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|