mirror of
https://github.com/shlinkio/shlink.git
synced 2026-03-06 23:33:13 +08:00
Allow individual real-time updates topics to be enabled
This commit is contained in:
@@ -85,6 +85,7 @@ enum EnvVars: string
|
||||
case MEMORY_LIMIT = 'MEMORY_LIMIT';
|
||||
case INITIAL_API_KEY = 'INITIAL_API_KEY';
|
||||
case SKIP_INITIAL_GEOLITE_DOWNLOAD = 'SKIP_INITIAL_GEOLITE_DOWNLOAD';
|
||||
case REAL_TIME_UPDATES_TOPICS = 'REAL_TIME_UPDATES_TOPICS';
|
||||
|
||||
/** @deprecated Use REDIRECT_EXTRA_PATH */
|
||||
case REDIRECT_APPEND_EXTRA_PATH = 'REDIRECT_APPEND_EXTRA_PATH';
|
||||
|
||||
39
module/Core/src/Config/Options/RealTimeUpdatesOptions.php
Normal file
39
module/Core/src/Config/Options/RealTimeUpdatesOptions.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Core\Config\Options;
|
||||
|
||||
use Shlinkio\Shlink\Core\Config\EnvVars;
|
||||
use Shlinkio\Shlink\Core\EventDispatcher\Topic;
|
||||
|
||||
use function count;
|
||||
use function Shlinkio\Shlink\Core\ArrayUtils\contains;
|
||||
use function Shlinkio\Shlink\Core\splitByComma;
|
||||
|
||||
final readonly class RealTimeUpdatesOptions
|
||||
{
|
||||
public array $enabledTopics;
|
||||
|
||||
public function __construct(array|null $enabledTopics = null)
|
||||
{
|
||||
$this->enabledTopics = $enabledTopics ?? Topic::allTopicNames();
|
||||
}
|
||||
|
||||
public static function fromEnv(): self
|
||||
{
|
||||
$enabledTopics = splitByComma(EnvVars::REAL_TIME_UPDATES_TOPICS->loadFromEnv());
|
||||
|
||||
return new self(
|
||||
enabledTopics: count($enabledTopics) === 0
|
||||
? Topic::allTopicNames()
|
||||
// TODO Validate provided topics are in fact Topic names
|
||||
: splitByComma(EnvVars::REAL_TIME_UPDATES_TOPICS->loadFromEnv()),
|
||||
);
|
||||
}
|
||||
|
||||
public function isTopicEnabled(Topic $topic): bool
|
||||
{
|
||||
return contains($topic->name, $this->enabledTopics);
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,10 @@ namespace Shlinkio\Shlink\Core\EventDispatcher\Async;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Shlinkio\Shlink\Common\UpdatePublishing\PublishingHelperInterface;
|
||||
use Shlinkio\Shlink\Core\Config\Options\RealTimeUpdatesOptions;
|
||||
use Shlinkio\Shlink\Core\EventDispatcher\Event\ShortUrlCreated;
|
||||
use Shlinkio\Shlink\Core\EventDispatcher\PublishingUpdatesGeneratorInterface;
|
||||
use Shlinkio\Shlink\Core\EventDispatcher\Topic;
|
||||
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
|
||||
use Throwable;
|
||||
|
||||
@@ -19,6 +21,7 @@ abstract class AbstractNotifyNewShortUrlListener extends AbstractAsyncListener
|
||||
private readonly PublishingUpdatesGeneratorInterface $updatesGenerator,
|
||||
private readonly EntityManagerInterface $em,
|
||||
private readonly LoggerInterface $logger,
|
||||
private readonly RealTimeUpdatesOptions $realTimeUpdatesOptions,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -40,6 +43,10 @@ abstract class AbstractNotifyNewShortUrlListener extends AbstractAsyncListener
|
||||
return;
|
||||
}
|
||||
|
||||
if (! $this->realTimeUpdatesOptions->isTopicEnabled(Topic::NEW_SHORT_URL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->publishingHelper->publishUpdate($this->updatesGenerator->newShortUrlUpdate($shortUrl));
|
||||
} catch (Throwable $e) {
|
||||
|
||||
@@ -8,8 +8,10 @@ use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Shlinkio\Shlink\Common\UpdatePublishing\PublishingHelperInterface;
|
||||
use Shlinkio\Shlink\Common\UpdatePublishing\Update;
|
||||
use Shlinkio\Shlink\Core\Config\Options\RealTimeUpdatesOptions;
|
||||
use Shlinkio\Shlink\Core\EventDispatcher\Event\UrlVisited;
|
||||
use Shlinkio\Shlink\Core\EventDispatcher\PublishingUpdatesGeneratorInterface;
|
||||
use Shlinkio\Shlink\Core\EventDispatcher\Topic;
|
||||
use Shlinkio\Shlink\Core\Visit\Entity\Visit;
|
||||
use Throwable;
|
||||
|
||||
@@ -22,6 +24,7 @@ abstract class AbstractNotifyVisitListener extends AbstractAsyncListener
|
||||
private readonly PublishingUpdatesGeneratorInterface $updatesGenerator,
|
||||
private readonly EntityManagerInterface $em,
|
||||
private readonly LoggerInterface $logger,
|
||||
private readonly RealTimeUpdatesOptions $realTimeUpdatesOptions,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -61,12 +64,19 @@ abstract class AbstractNotifyVisitListener extends AbstractAsyncListener
|
||||
protected function determineUpdatesForVisit(Visit $visit): array
|
||||
{
|
||||
if ($visit->isOrphan()) {
|
||||
return [$this->updatesGenerator->newOrphanVisitUpdate($visit)];
|
||||
return $this->realTimeUpdatesOptions->isTopicEnabled(Topic::NEW_ORPHAN_VISIT)
|
||||
? [$this->updatesGenerator->newOrphanVisitUpdate($visit)]
|
||||
: [];
|
||||
}
|
||||
|
||||
return [
|
||||
$this->updatesGenerator->newShortUrlVisitUpdate($visit),
|
||||
$this->updatesGenerator->newVisitUpdate($visit),
|
||||
];
|
||||
$topics = [];
|
||||
if ($this->realTimeUpdatesOptions->isTopicEnabled(Topic::NEW_SHORT_URL_VISIT)) {
|
||||
$topics[] = $this->updatesGenerator->newShortUrlVisitUpdate($visit);
|
||||
}
|
||||
if ($this->realTimeUpdatesOptions->isTopicEnabled(Topic::NEW_VISIT)) {
|
||||
$topics[] = $this->updatesGenerator->newVisitUpdate($visit);
|
||||
}
|
||||
|
||||
return $topics;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Shlinkio\Shlink\Common\UpdatePublishing\PublishingHelperInterface;
|
||||
use Shlinkio\Shlink\Core\Config\Options\RabbitMqOptions;
|
||||
use Shlinkio\Shlink\Core\Config\Options\RealTimeUpdatesOptions;
|
||||
use Shlinkio\Shlink\Core\EventDispatcher\Async\AbstractNotifyNewShortUrlListener;
|
||||
use Shlinkio\Shlink\Core\EventDispatcher\Async\RemoteSystem;
|
||||
use Shlinkio\Shlink\Core\EventDispatcher\PublishingUpdatesGeneratorInterface;
|
||||
@@ -19,9 +20,10 @@ class NotifyNewShortUrlToRabbitMq extends AbstractNotifyNewShortUrlListener
|
||||
PublishingUpdatesGeneratorInterface $updatesGenerator,
|
||||
EntityManagerInterface $em,
|
||||
LoggerInterface $logger,
|
||||
RealTimeUpdatesOptions $realTimeUpdatesOptions,
|
||||
private readonly RabbitMqOptions $options,
|
||||
) {
|
||||
parent::__construct($rabbitMqHelper, $updatesGenerator, $em, $logger);
|
||||
parent::__construct($rabbitMqHelper, $updatesGenerator, $em, $logger, $realTimeUpdatesOptions);
|
||||
}
|
||||
|
||||
protected function isEnabled(): bool
|
||||
|
||||
@@ -8,6 +8,7 @@ use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Shlinkio\Shlink\Common\UpdatePublishing\PublishingHelperInterface;
|
||||
use Shlinkio\Shlink\Core\Config\Options\RabbitMqOptions;
|
||||
use Shlinkio\Shlink\Core\Config\Options\RealTimeUpdatesOptions;
|
||||
use Shlinkio\Shlink\Core\EventDispatcher\Async\AbstractNotifyVisitListener;
|
||||
use Shlinkio\Shlink\Core\EventDispatcher\Async\RemoteSystem;
|
||||
use Shlinkio\Shlink\Core\EventDispatcher\PublishingUpdatesGeneratorInterface;
|
||||
@@ -19,9 +20,10 @@ class NotifyVisitToRabbitMq extends AbstractNotifyVisitListener
|
||||
PublishingUpdatesGeneratorInterface $updatesGenerator,
|
||||
EntityManagerInterface $em,
|
||||
LoggerInterface $logger,
|
||||
RealTimeUpdatesOptions $realTimeUpdatesOptions,
|
||||
private readonly RabbitMqOptions $options,
|
||||
) {
|
||||
parent::__construct($rabbitMqHelper, $updatesGenerator, $em, $logger);
|
||||
parent::__construct($rabbitMqHelper, $updatesGenerator, $em, $logger, $realTimeUpdatesOptions);
|
||||
}
|
||||
|
||||
protected function isEnabled(): bool
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace Shlinkio\Shlink\Core\EventDispatcher\RedisPubSub;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Shlinkio\Shlink\Common\UpdatePublishing\PublishingHelperInterface;
|
||||
use Shlinkio\Shlink\Core\Config\Options\RealTimeUpdatesOptions;
|
||||
use Shlinkio\Shlink\Core\EventDispatcher\Async\AbstractNotifyNewShortUrlListener;
|
||||
use Shlinkio\Shlink\Core\EventDispatcher\Async\RemoteSystem;
|
||||
use Shlinkio\Shlink\Core\EventDispatcher\PublishingUpdatesGeneratorInterface;
|
||||
@@ -18,9 +19,10 @@ class NotifyNewShortUrlToRedis extends AbstractNotifyNewShortUrlListener
|
||||
PublishingUpdatesGeneratorInterface $updatesGenerator,
|
||||
EntityManagerInterface $em,
|
||||
LoggerInterface $logger,
|
||||
RealTimeUpdatesOptions $realTimeUpdatesOptions,
|
||||
private readonly bool $enabled,
|
||||
) {
|
||||
parent::__construct($redisHelper, $updatesGenerator, $em, $logger);
|
||||
parent::__construct($redisHelper, $updatesGenerator, $em, $logger, $realTimeUpdatesOptions);
|
||||
}
|
||||
|
||||
protected function isEnabled(): bool
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace Shlinkio\Shlink\Core\EventDispatcher\RedisPubSub;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Shlinkio\Shlink\Common\UpdatePublishing\PublishingHelperInterface;
|
||||
use Shlinkio\Shlink\Core\Config\Options\RealTimeUpdatesOptions;
|
||||
use Shlinkio\Shlink\Core\EventDispatcher\Async\AbstractNotifyVisitListener;
|
||||
use Shlinkio\Shlink\Core\EventDispatcher\Async\RemoteSystem;
|
||||
use Shlinkio\Shlink\Core\EventDispatcher\PublishingUpdatesGeneratorInterface;
|
||||
@@ -18,9 +19,10 @@ class NotifyVisitToRedis extends AbstractNotifyVisitListener
|
||||
PublishingUpdatesGeneratorInterface $updatesGenerator,
|
||||
EntityManagerInterface $em,
|
||||
LoggerInterface $logger,
|
||||
RealTimeUpdatesOptions $realTimeUpdatesOptions,
|
||||
private readonly bool $enabled,
|
||||
) {
|
||||
parent::__construct($redisHelper, $updatesGenerator, $em, $logger);
|
||||
parent::__construct($redisHelper, $updatesGenerator, $em, $logger, $realTimeUpdatesOptions);
|
||||
}
|
||||
|
||||
protected function isEnabled(): bool
|
||||
|
||||
@@ -4,16 +4,23 @@ declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Core\EventDispatcher;
|
||||
|
||||
use function Shlinkio\Shlink\Core\enumNames;
|
||||
use function sprintf;
|
||||
|
||||
enum Topic: string
|
||||
{
|
||||
case NEW_VISIT = 'https://shlink.io/new-visit';
|
||||
case NEW_SHORT_URL_VISIT = 'https://shlink.io/new-visit/%s';
|
||||
case NEW_ORPHAN_VISIT = 'https://shlink.io/new-orphan-visit';
|
||||
case NEW_SHORT_URL = 'https://shlink.io/new-short-url';
|
||||
|
||||
public static function newShortUrlVisit(string|null $shortCode): string
|
||||
{
|
||||
return sprintf('%s/%s', self::NEW_VISIT->value, $shortCode ?? '');
|
||||
return sprintf(self::NEW_SHORT_URL_VISIT->value, $shortCode ?? '');
|
||||
}
|
||||
|
||||
public static function allTopicNames(): array
|
||||
{
|
||||
return enumNames(self::class);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user