Skip to content

Commit 062304f

Browse files
Implement NamespacedPoolInterface for TraceableCacheAdapterForV3 (#927)
1 parent ed34b0c commit 062304f

File tree

3 files changed

+84
-1
lines changed

3 files changed

+84
-1
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sentry\SentryBundle\Tracing\Cache;
6+
7+
use Sentry\State\HubInterface;
8+
use Symfony\Component\Cache\Adapter\AdapterInterface;
9+
use Symfony\Component\Cache\PruneableInterface;
10+
use Symfony\Component\Cache\ResettableInterface;
11+
use Symfony\Contracts\Cache\CacheInterface;
12+
use Symfony\Contracts\Cache\NamespacedPoolInterface;
13+
14+
/**
15+
* This implementation of a cache adapter supports the distributed tracing
16+
* feature of Sentry.
17+
*
18+
* @internal
19+
*/
20+
final class TraceableCacheAdapterForV3WithNamespace implements AdapterInterface, NamespacedPoolInterface, CacheInterface, PruneableInterface, ResettableInterface
21+
{
22+
/**
23+
* @phpstan-use TraceableCacheAdapterTrait<AdapterInterface>
24+
*/
25+
use TraceableCacheAdapterTrait;
26+
27+
/**
28+
* @param HubInterface $hub The current hub
29+
* @param AdapterInterface $decoratedAdapter The decorated cache adapter
30+
*/
31+
public function __construct(HubInterface $hub, AdapterInterface $decoratedAdapter)
32+
{
33+
$this->hub = $hub;
34+
$this->decoratedAdapter = $decoratedAdapter;
35+
}
36+
37+
/**
38+
* {@inheritdoc}
39+
*
40+
* @param mixed[] $metadata
41+
*/
42+
public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null): mixed
43+
{
44+
return $this->traceFunction('cache.get_item', function () use ($key, $callback, $beta, &$metadata) {
45+
if (!$this->decoratedAdapter instanceof CacheInterface) {
46+
throw new \BadMethodCallException(\sprintf('The %s::get() method is not supported because the decorated adapter does not implement the "%s" interface.', self::class, CacheInterface::class));
47+
}
48+
49+
return $this->decoratedAdapter->get($key, $callback, $beta, $metadata);
50+
}, $key);
51+
}
52+
53+
public function withSubNamespace(string $namespace): static
54+
{
55+
if (!$this->decoratedAdapter instanceof NamespacedPoolInterface) {
56+
throw new \BadMethodCallException(\sprintf('The %s::withSubNamespace() method is not supported because the decorated adapter does not implement the "%s" interface.', self::class, NamespacedPoolInterface::class));
57+
}
58+
59+
$clone = clone $this;
60+
$clone->decoratedAdapter = $this->decoratedAdapter->withSubNamespace($namespace);
61+
62+
return $clone;
63+
}
64+
}

src/aliases.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Sentry\SentryBundle\Tracing\Cache\TraceableCacheAdapter;
1010
use Sentry\SentryBundle\Tracing\Cache\TraceableCacheAdapterForV2;
1111
use Sentry\SentryBundle\Tracing\Cache\TraceableCacheAdapterForV3;
12+
use Sentry\SentryBundle\Tracing\Cache\TraceableCacheAdapterForV3WithNamespace;
1213
use Sentry\SentryBundle\Tracing\Cache\TraceableTagAwareCacheAdapter;
1314
use Sentry\SentryBundle\Tracing\Cache\TraceableTagAwareCacheAdapterForV2;
1415
use Sentry\SentryBundle\Tracing\Cache\TraceableTagAwareCacheAdapterForV3;
@@ -38,12 +39,17 @@
3839
use Symfony\Component\Cache\DoctrineProvider;
3940
use Symfony\Component\HttpClient\HttpClient;
4041
use Symfony\Component\HttpClient\Response\StreamableInterface;
42+
use Symfony\Contracts\Cache\NamespacedPoolInterface;
4143
use Symfony\Contracts\HttpClient\HttpClientInterface;
4244

4345
if (interface_exists(AdapterInterface::class)) {
4446
if (!class_exists(DoctrineProvider::class, false) && version_compare(\PHP_VERSION, '8.0.0', '>=')) {
4547
if (!class_exists(TraceableCacheAdapter::class, false)) {
46-
class_alias(TraceableCacheAdapterForV3::class, TraceableCacheAdapter::class);
48+
if (interface_exists(NamespacedPoolInterface::class)) {
49+
class_alias(TraceableCacheAdapterForV3WithNamespace::class, TraceableCacheAdapter::class);
50+
} else {
51+
class_alias(TraceableCacheAdapterForV3::class, TraceableCacheAdapter::class);
52+
}
4753
}
4854

4955
if (!class_exists(TraceableTagAwareCacheAdapter::class, false)) {

tests/Tracing/Cache/TraceableCacheAdapterTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Sentry\SentryBundle\Tracing\Cache\TraceableCacheAdapter;
88
use Symfony\Component\Cache\Adapter\AdapterInterface;
9+
use Symfony\Contracts\Cache\NamespacedPoolInterface;
910

1011
/**
1112
* @phpstan-extends AbstractTraceableCacheAdapterTest<TraceableCacheAdapter, AdapterInterface>
@@ -27,4 +28,16 @@ protected static function getAdapterClassFqcn(): string
2728
{
2829
return AdapterInterface::class;
2930
}
31+
32+
public function testNamespacePoolImplementation(): void
33+
{
34+
if (!interface_exists(NamespacedPoolInterface::class)) {
35+
$this->markTestSkipped('NamespacedPoolInterface does not exists.');
36+
}
37+
38+
$decoratedAdapter = $this->createMock(static::getAdapterClassFqcn());
39+
$adapter = $this->createCacheAdapter($decoratedAdapter);
40+
41+
static::assertInstanceOf(NamespacedPoolInterface::class, $adapter);
42+
}
3043
}

0 commit comments

Comments
 (0)