Skip to content

Commit

Permalink
chore: remove dependency on thecodingmachine/cache-utils
Browse files Browse the repository at this point in the history
The package seems to be unmaintained and prevents usage due to old
psr/simple-cache. This removes the dependency on that package.
The package provided cache clearance on Classes and ParentClasses when their files changed.
This functionality can still be achieved by creating a custom implementation of
`TheCodingMachine\GraphQLite\Utils\Cache\ClassBoundCacheContractFactoryInterface`.

fixes #693
  • Loading branch information
xyng committed Jul 16, 2024
1 parent 81094e9 commit 85c3ca1
Show file tree
Hide file tree
Showing 12 changed files with 128 additions and 25 deletions.
1 change: 0 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
"psr/simple-cache": "^1.0.1 || ^2 || ^3",
"symfony/cache": "^4.3 || ^5 || ^6 || ^7",
"symfony/expression-language": "^4 || ^5 || ^6 || ^7",
"thecodingmachine/cache-utils": "^1",
"webonyx/graphql-php": "^v15.0",
"kcs/class-finder": "^0.5.0"
},
Expand Down
42 changes: 42 additions & 0 deletions src/Cache/ClassBoundCacheContract.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

namespace TheCodingMachine\GraphQLite\Cache;

use Psr\SimpleCache\CacheInterface;
use Psr\SimpleCache\InvalidArgumentException;
use ReflectionClass;
use function str_replace;

class ClassBoundCacheContract implements ClassBoundCacheContractInterface
{
private readonly string $cachePrefix;

public function __construct(private readonly CacheInterface $classBoundCache, string $cachePrefix = '')
{
$this->cachePrefix = str_replace(['\\', '{', '}', '(', ')', '/', '@', ':'], '_', $cachePrefix);
}

/**
* @param string $key An optional key to differentiate between cache items attached to the same class.
*
* @throws InvalidArgumentException
*/
public function get(ReflectionClass $reflectionClass, callable $resolver, string $key = '', int|null $ttl = null): mixed
{
$cacheKey = $reflectionClass->getName() . '__' . $key;
$cacheKey = $this->cachePrefix . str_replace(['\\', '{', '}', '(', ')', '/', '@', ':'], '_', $cacheKey);

$item = $this->classBoundCache->get($cacheKey);
if ($item !== null) {
return $item;
}

$item = $resolver();

$this->classBoundCache->set($cacheKey, $item, $ttl);

return $item;
}
}
15 changes: 15 additions & 0 deletions src/Cache/ClassBoundCacheContractFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace TheCodingMachine\GraphQLite\Cache;

use Psr\SimpleCache\CacheInterface;

class ClassBoundCacheContractFactory implements ClassBoundCacheContractFactoryInterface
{
public function make(CacheInterface $classBoundCache, string $cachePrefix = ''): ClassBoundCacheContractInterface
{
return new ClassBoundCacheContract($classBoundCache, $cachePrefix);
}
}
12 changes: 12 additions & 0 deletions src/Cache/ClassBoundCacheContractFactoryInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace TheCodingMachine\GraphQLite\Cache;

use Psr\SimpleCache\CacheInterface;

interface ClassBoundCacheContractFactoryInterface
{
public function make(CacheInterface $classBoundCache, string $cachePrefix = ''): ClassBoundCacheContractInterface;
}
18 changes: 18 additions & 0 deletions src/Cache/ClassBoundCacheContractInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace TheCodingMachine\GraphQLite\Cache;

use ReflectionClass;

interface ClassBoundCacheContractInterface
{
/**
* @param string $key An optional key to differentiate between cache items attached to the same class.
*
* @return mixed
*/
public function get(ReflectionClass $reflectionClass, callable $resolver, string $key = '', ?int $ttl = null);
}

6 changes: 6 additions & 0 deletions src/FactoryContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Psr\Container\ContainerInterface;
use Psr\SimpleCache\CacheInterface;
use TheCodingMachine\GraphQLite\Cache\ClassBoundCacheContractFactoryInterface;
use TheCodingMachine\GraphQLite\Mappers\RecursiveTypeMapperInterface;
use TheCodingMachine\GraphQLite\Types\InputTypeValidatorInterface;
use TheCodingMachine\GraphQLite\Types\TypeResolver;
Expand All @@ -31,6 +32,7 @@ public function __construct(
private readonly InputTypeValidatorInterface|null $inputTypeValidator,
private readonly int|null $globTTL,
private readonly int|null $mapTTL = null,
private readonly ClassBoundCacheContractFactoryInterface|null $classBoundCacheContractFactory = null,
) {
}

Expand Down Expand Up @@ -84,6 +86,10 @@ public function getCache(): CacheInterface
return $this->cache;
}

public function getClassBoundCacheContractFactory(): ?ClassBoundCacheContractFactoryInterface {
return $this->classBoundCacheContractFactory;
}

public function getInputTypeValidator(): InputTypeValidatorInterface|null
{
return $this->inputTypeValidator;
Expand Down
27 changes: 8 additions & 19 deletions src/Mappers/AbstractTypeMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@
use ReflectionMethod;
use Symfony\Component\Cache\Adapter\Psr16Adapter;
use Symfony\Contracts\Cache\CacheInterface as CacheContractInterface;
use TheCodingMachine\CacheUtils\ClassBoundCache;
use TheCodingMachine\CacheUtils\ClassBoundCacheContract;
use TheCodingMachine\CacheUtils\ClassBoundCacheContractInterface;
use TheCodingMachine\CacheUtils\ClassBoundMemoryAdapter;
use TheCodingMachine\CacheUtils\FileBoundCache;
use TheCodingMachine\GraphQLite\AnnotationReader;
use TheCodingMachine\GraphQLite\Cache\ClassBoundCacheContractFactory;
use TheCodingMachine\GraphQLite\Cache\ClassBoundCacheContractFactoryInterface;
use TheCodingMachine\GraphQLite\Cache\ClassBoundCacheContractInterface;
use TheCodingMachine\GraphQLite\InputTypeGenerator;
use TheCodingMachine\GraphQLite\InputTypeUtils;
use TheCodingMachine\GraphQLite\NamingStrategyInterface;
Expand All @@ -29,7 +27,6 @@
use TheCodingMachine\GraphQLite\Types\MutableInterfaceType;
use TheCodingMachine\GraphQLite\Types\MutableObjectType;
use TheCodingMachine\GraphQLite\Types\ResolvableMutableInputInterface;

use function assert;

/**
Expand Down Expand Up @@ -66,23 +63,15 @@ public function __construct(
private readonly CacheInterface $cache,
protected int|null $globTTL = 2,
private readonly int|null $mapTTL = null,
ClassBoundCacheContractFactoryInterface|null $classBoundCacheContractFactory = null,
)
{
$this->cacheContract = new Psr16Adapter($this->cache, $cachePrefix, $this->globTTL ?? 0);

$classToAnnotationsCache = new ClassBoundCache(
new FileBoundCache($this->cache, 'classToAnnotations_' . $cachePrefix),
);
$this->mapClassToAnnotationsCache = new ClassBoundCacheContract(
new ClassBoundMemoryAdapter($classToAnnotationsCache),
);

$classToExtendedAnnotationsCache = new ClassBoundCache(
new FileBoundCache($this->cache, 'classToExtendAnnotations_' . $cachePrefix),
);
$this->mapClassToExtendAnnotationsCache = new ClassBoundCacheContract(
new ClassBoundMemoryAdapter($classToExtendedAnnotationsCache),
);
$classBoundCacheContractFactory = $classBoundCacheContractFactory ?? new ClassBoundCacheContractFactory();

$this->mapClassToAnnotationsCache = $classBoundCacheContractFactory->make($cache, 'classToAnnotations_' . $cachePrefix);
$this->mapClassToExtendAnnotationsCache = $classBoundCacheContractFactory->make($cache, 'classToExtendAnnotations_' . $cachePrefix);
}

/**
Expand Down
4 changes: 3 additions & 1 deletion src/Mappers/GlobTypeMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
use Psr\SimpleCache\CacheInterface;
use ReflectionClass;
use TheCodingMachine\GraphQLite\AnnotationReader;
use TheCodingMachine\GraphQLite\Cache\ClassBoundCacheContractFactoryInterface;
use TheCodingMachine\GraphQLite\InputTypeGenerator;
use TheCodingMachine\GraphQLite\InputTypeUtils;
use TheCodingMachine\GraphQLite\NamingStrategyInterface;
use TheCodingMachine\GraphQLite\TypeGenerator;
use TheCodingMachine\GraphQLite\Utils\Namespaces\NS;

use function str_replace;

/**
Expand Down Expand Up @@ -44,6 +44,7 @@ public function __construct(
CacheInterface $cache,
int|null $globTTL = 2,
int|null $mapTTL = null,
ClassBoundCacheContractFactoryInterface|null $classBoundCacheContractFactory = null,
) {
$cachePrefix = str_replace(
['\\', '{', '}', '(', ')', '/', '@', ':'],
Expand All @@ -63,6 +64,7 @@ public function __construct(
$cache,
$globTTL,
$mapTTL,
$classBoundCacheContractFactory,
);
}

Expand Down
4 changes: 3 additions & 1 deletion src/Mappers/StaticClassListTypeMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
use Psr\SimpleCache\CacheInterface;
use ReflectionClass;
use TheCodingMachine\GraphQLite\AnnotationReader;
use TheCodingMachine\GraphQLite\Cache\ClassBoundCacheContractFactoryInterface;
use TheCodingMachine\GraphQLite\GraphQLRuntimeException;
use TheCodingMachine\GraphQLite\InputTypeGenerator;
use TheCodingMachine\GraphQLite\InputTypeUtils;
use TheCodingMachine\GraphQLite\NamingStrategyInterface;
use TheCodingMachine\GraphQLite\TypeGenerator;

use function class_exists;
use function implode;
use function interface_exists;
Expand Down Expand Up @@ -45,6 +45,7 @@ public function __construct(
CacheInterface $cache,
int|null $globTTL = 2,
int|null $mapTTL = null,
ClassBoundCacheContractFactoryInterface|null $classBoundCacheContractFactory = null,
) {
$cachePrefix = str_replace(
['\\', '{', '}', '(', ')', '/', '@', ':'],
Expand All @@ -64,6 +65,7 @@ public function __construct(
$cache,
$globTTL,
$mapTTL,
$classBoundCacheContractFactory,
);
}

Expand Down
1 change: 1 addition & 0 deletions src/Mappers/StaticClassListTypeMapperFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public function create(FactoryContext $context): TypeMapperInterface
$context->getNamingStrategy(),
$context->getRecursiveTypeMapper(),
$context->getCache(),
$context->getClassBoundCacheContractFactory(),

Check failure on line 39 in src/Mappers/StaticClassListTypeMapperFactory.php

View workflow job for this annotation

GitHub Actions / Continuous Integration (--prefer-lowest, 8.1)

Parameter #10 $globTTL of class TheCodingMachine\GraphQLite\Mappers\StaticClassListTypeMapper constructor expects int|null, TheCodingMachine\GraphQLite\Cache\ClassBoundCacheContractFactoryInterface|null given.

Check failure on line 39 in src/Mappers/StaticClassListTypeMapperFactory.php

View workflow job for this annotation

GitHub Actions / Continuous Integration (--prefer-lowest, 8.2)

Parameter #10 $globTTL of class TheCodingMachine\GraphQLite\Mappers\StaticClassListTypeMapper constructor expects int|null, TheCodingMachine\GraphQLite\Cache\ClassBoundCacheContractFactoryInterface|null given.

Check failure on line 39 in src/Mappers/StaticClassListTypeMapperFactory.php

View workflow job for this annotation

GitHub Actions / Continuous Integration (--prefer-lowest, 8.3)

Parameter #10 $globTTL of class TheCodingMachine\GraphQLite\Mappers\StaticClassListTypeMapper constructor expects int|null, TheCodingMachine\GraphQLite\Cache\ClassBoundCacheContractFactoryInterface|null given.
$context->getGlobTTL(),
$context->getMapTTL(),

Check failure on line 41 in src/Mappers/StaticClassListTypeMapperFactory.php

View workflow job for this annotation

GitHub Actions / Continuous Integration (--prefer-lowest, 8.1)

Parameter #12 $classBoundCacheContractFactory of class TheCodingMachine\GraphQLite\Mappers\StaticClassListTypeMapper constructor expects TheCodingMachine\GraphQLite\Cache\ClassBoundCacheContractFactoryInterface|null, int|null given.

Check failure on line 41 in src/Mappers/StaticClassListTypeMapperFactory.php

View workflow job for this annotation

GitHub Actions / Continuous Integration (--prefer-lowest, 8.2)

Parameter #12 $classBoundCacheContractFactory of class TheCodingMachine\GraphQLite\Mappers\StaticClassListTypeMapper constructor expects TheCodingMachine\GraphQLite\Cache\ClassBoundCacheContractFactoryInterface|null, int|null given.

Check failure on line 41 in src/Mappers/StaticClassListTypeMapperFactory.php

View workflow job for this annotation

GitHub Actions / Continuous Integration (--prefer-lowest, 8.3)

Parameter #12 $classBoundCacheContractFactory of class TheCodingMachine\GraphQLite\Mappers\StaticClassListTypeMapper constructor expects TheCodingMachine\GraphQLite\Cache\ClassBoundCacheContractFactoryInterface|null, int|null given.
);
Expand Down
18 changes: 16 additions & 2 deletions src/SchemaFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Psr\SimpleCache\CacheInterface;
use Symfony\Component\Cache\Adapter\Psr16Adapter;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
use TheCodingMachine\GraphQLite\Cache\ClassBoundCacheContractFactoryInterface;
use TheCodingMachine\GraphQLite\Mappers\CompositeTypeMapper;
use TheCodingMachine\GraphQLite\Mappers\GlobTypeMapper;
use TheCodingMachine\GraphQLite\Mappers\Parameters\ContainerParameterHandler;
Expand Down Expand Up @@ -56,7 +57,6 @@
use TheCodingMachine\GraphQLite\Types\TypeResolver;
use TheCodingMachine\GraphQLite\Utils\NamespacedCache;
use TheCodingMachine\GraphQLite\Utils\Namespaces\NamespaceFactory;

use function array_map;
use function array_reverse;
use function class_exists;
Expand Down Expand Up @@ -120,7 +120,7 @@ class SchemaFactory

private string $cacheNamespace;

public function __construct(private readonly CacheInterface $cache, private readonly ContainerInterface $container)
public function __construct(private readonly CacheInterface $cache, private readonly ContainerInterface $container, private ?ClassBoundCacheContractFactoryInterface $classBoundCacheContractFactory = null)
{
$this->cacheNamespace = substr(md5(Versions::getVersion('thecodingmachine/graphqlite')), 0, 8);
}
Expand Down Expand Up @@ -259,6 +259,18 @@ public function setGlobTTL(int|null $globTTL): self
return $this;
}

/**
* Set a custom ClassBoundCacheContractFactory.
* This is used to create CacheContracts that store reflection results.
* Set this to "null" to use the default fallback factory.
*/
public function setClassBoundCacheContractFactory(ClassBoundCacheContractFactoryInterface|null $classBoundCacheContractFactory): self
{
$this->classBoundCacheContractFactory = $classBoundCacheContractFactory;

return $this;
}

/**
* Sets GraphQLite in "prod" mode (cache settings optimized for best performance).
*
Expand Down Expand Up @@ -430,6 +442,7 @@ public function createSchema(): Schema
$recursiveTypeMapper,
$namespacedCache,
$this->globTTL,
classBoundCacheContractFactory: $this->classBoundCacheContractFactory,
));
}

Expand All @@ -447,6 +460,7 @@ public function createSchema(): Schema
$namespacedCache,
$this->inputTypeValidator,
$this->globTTL,
classBoundCacheContractFactory: $this->classBoundCacheContractFactory,
);
}

Expand Down
5 changes: 4 additions & 1 deletion tests/FactoryContextTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Psr16Cache;
use TheCodingMachine\GraphQLite\Cache\ClassBoundCacheContractFactory;
use TheCodingMachine\GraphQLite\Containers\EmptyContainer;
use TheCodingMachine\GraphQLite\Fixtures\Inputs\Validator;

Expand All @@ -16,6 +17,7 @@ public function testContext(): void
$namingStrategy = new NamingStrategy();
$container = new EmptyContainer();
$arrayCache = new Psr16Cache(new ArrayAdapter());
$classBoundCacheContractFactory = new ClassBoundCacheContractFactory();
$validator = new Validator();

$context = new FactoryContext(
Expand All @@ -30,7 +32,8 @@ public function testContext(): void
$container,
$arrayCache,
$validator,
self::GLOB_TTL_SECONDS
self::GLOB_TTL_SECONDS,
classBoundCacheContractFactory: $classBoundCacheContractFactory,
);

$this->assertSame($this->getAnnotationReader(), $context->getAnnotationReader());
Expand Down

0 comments on commit 85c3ca1

Please sign in to comment.