Skip to content

Commit

Permalink
Multiple cache services
Browse files Browse the repository at this point in the history
- added service of type `CacheRegistryInterface`
- added property `cacheName` to the `CacheMetadata` and `InvalidateCacheCommand` classes
- added `memory` cache into the DIC
  • Loading branch information
tg666 committed Mar 1, 2024
1 parent 9e4b902 commit 03c5070
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ final class InvalidateCacheCommand implements CommandInterface
public function __construct(
public readonly array $keys = [],
public readonly array $tags = [],
public readonly ?string $cacheName = null,
) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,29 @@

use SixtyEightPublishers\ArchitectureBundle\Application\Command\InvalidateCacheCommand;
use SixtyEightPublishers\ArchitectureBundle\Command\CommandHandlerInterface;
use SixtyEightPublishers\ArchitectureBundle\Infrastructure\Cache\CacheInterface;
use SixtyEightPublishers\ArchitectureBundle\Infrastructure\Cache\CacheRegistryInterface;
use function count;

final class InvalidateCacheCommandHandler implements CommandHandlerInterface
{
public function __construct(
private readonly CacheInterface $cache,
private readonly CacheRegistryInterface $cacheRegistry,
) {}

public function __invoke(InvalidateCacheCommand $command): void
{
$cache = $this->cacheRegistry->getCache(
name: $command->cacheName,
);

foreach ($command->keys as $key) {
$this->cache->deleteItem(
$cache->deleteItem(
key: $key,
);
}

if (0 < count($command->tags)) {
$this->cache->clean(
$cache->clean(
tags: $command->tags,
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,28 @@
services:
infrastructure.cache_registry:
autowired: SixtyEightPublishers\ArchitectureBundle\Infrastructure\Cache\CacheRegistryInterface
type: SixtyEightPublishers\ArchitectureBundle\Infrastructure\Cache\CacheRegistryInterface
factory: @extension.infrastructure.cache_registry.default

infrastructure.cache_registry.default:
autowired: no
factory: SixtyEightPublishers\ArchitectureBundle\Infrastructure\Cache\CacheRegistry(
cacheServices: [
memory: @extension.infrastructure.cache.memory
]
)

infrastructure.cache:
autowired: SixtyEightPublishers\ArchitectureBundle\Infrastructure\Cache\CacheInterface
type: SixtyEightPublishers\ArchitectureBundle\Infrastructure\Cache\CacheInterface
factory: @extension.infrastructure.cache.nette
factory: @extension.infrastructure.cache.default

infrastructure.cache.nette:
infrastructure.cache.default:
autowired: no
factory: SixtyEightPublishers\ArchitectureBundle\Infrastructure\NetteCache\NetteCache

infrastructure.cache.memory:
autowired: no
factory: SixtyEightPublishers\ArchitectureBundle\Infrastructure\NetteCache\NetteCache(
storage: Nette\Caching\Storages\MemoryStorage(),
)
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
namespace SixtyEightPublishers\ArchitectureBundle\Bridge\Symfony\Messenger\Middleware;

use Psr\Log\LoggerInterface;
use SixtyEightPublishers\ArchitectureBundle\Bridge\Symfony\Messenger\Stamp\CacheStamp;
use SixtyEightPublishers\ArchitectureBundle\Bridge\Symfony\Messenger\Stamp\RefreshCacheStamp;
use SixtyEightPublishers\ArchitectureBundle\Infrastructure\Cache\CacheInterface;
use SixtyEightPublishers\ArchitectureBundle\Infrastructure\Cache\CacheRegistryInterface;
use SixtyEightPublishers\ArchitectureBundle\Infrastructure\Cache\UnableToReadCacheException;
use SixtyEightPublishers\ArchitectureBundle\Infrastructure\Cache\UnableToWriteCacheException;
use SixtyEightPublishers\ArchitectureBundle\ReadModel\Query\CachableQueryInterface;
Expand All @@ -17,26 +18,30 @@
final class QueryCacheMiddleware implements MiddlewareInterface
{
public function __construct(
private readonly CacheInterface $cache,
private readonly CacheRegistryInterface $cacheRegistry,
private readonly ?LoggerInterface $logger = null,
) {}

public function handle(Envelope $envelope, StackInterface $stack): Envelope
{
$message = $envelope->getMessage();
$cacheStamp = $envelope->last(CacheStamp::class);

if (!($message instanceof CachableQueryInterface)) {
if (!($message instanceof CachableQueryInterface) && !($cacheStamp instanceof CacheStamp)) {
return $stack->next()->handle(
envelope: $envelope,
stack: $stack,
);
}

$cacheMetadata = $cacheStamp instanceof CacheStamp ? $cacheStamp->metadata : $message->createCacheMetadata();
$cache = $this->cacheRegistry->getCache(
name: $cacheMetadata->cacheName,
);
$refreshCache = $envelope->last(RefreshCacheStamp::class) !== null;
$cacheMetadata = $message->createCacheMetadata();

try {
$item = !$refreshCache ? $this->cache->getItem(
$item = !$refreshCache ? $cache->getItem(
key: $cacheMetadata->key,
) : null;
} catch (UnableToReadCacheException $e) {
Expand Down Expand Up @@ -64,7 +69,7 @@ public function handle(Envelope $envelope, StackInterface $stack): Envelope
);

try {
$this->cache->saveItem(
$cache->saveItem(
metadata: $cacheMetadata,
item: $item,
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace SixtyEightPublishers\ArchitectureBundle\Bridge\Symfony\Messenger\Stamp;

use SixtyEightPublishers\ArchitectureBundle\Infrastructure\Cache\CacheMetadata;
use Symfony\Component\Messenger\Stamp\StampInterface;

final class CacheStamp implements StampInterface
{
public function __construct(
public readonly CacheMetadata $metadata,
) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ public function __construct(
public readonly string $key,
public readonly int|DateTimeImmutable|null $expiration,
public readonly array $tags = [],
public readonly ?string $cacheName = null,
) {}
}
36 changes: 36 additions & 0 deletions src/ArchitectureBundle/Infrastructure/Cache/CacheRegistry.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

namespace SixtyEightPublishers\ArchitectureBundle\Infrastructure\Cache;

final class CacheRegistry implements CacheRegistryInterface
{
/**
* @param array<string, CacheInterface> $cacheServices
*/
public function __construct(
private readonly CacheInterface $defaultCacheService,
private array $cacheServices = [],
) {}

public function addCacheService(string $name, CacheInterface $cache): void
{
$this->cacheServices[$name] = $cache;
}

public function getCache(?string $name): CacheInterface
{
if (null === $name) {
return $this->defaultCacheService;
}

if (!isset($this->cacheServices[$name])) {
throw MissingCacheServiceException::create(
name: $name,
);
}

return $this->cacheServices[$name];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

declare(strict_types=1);

namespace SixtyEightPublishers\ArchitectureBundle\Infrastructure\Cache;

interface CacheRegistryInterface
{
/**
* @throws MissingCacheServiceException
*/
public function getCache(?string $name): CacheInterface;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace SixtyEightPublishers\ArchitectureBundle\Infrastructure\Cache;

use InvalidArgumentException;
use function sprintf;

final class MissingCacheServiceException extends InvalidArgumentException
{
public static function create(string $name): self
{
return new self(
message: sprintf(
'Cache service "%s" is missing.',
$name,
),
);
}
}

0 comments on commit 03c5070

Please sign in to comment.