Skip to content

Commit

Permalink
chore: remove dependency on thecodingmachine/cache-utils (#695)
Browse files Browse the repository at this point in the history
* chore: remove dependency on thecodingmachine/cache-utils

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

* fix: correctly escape `|` in phpstan ignoreErrors

* fix: sync min symfony/cache version of library to example and solve deprecation

This is necessary because symfony/cache is not compatible with every supported
version of psr/simple-cache.
More info here: symfony/symfony#44738
  • Loading branch information
xyng authored Jul 16, 2024
1 parent 81094e9 commit 069d62a
Show file tree
Hide file tree
Showing 15 changed files with 131 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
3 changes: 2 additions & 1 deletion examples/no-framework/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"require": {
"thecodingmachine/graphqlite": "@dev",
"mouf/picotainer": "^1.1",
"symfony/cache": "^4.2"
"symfony/cache": "^4.3",
"psr/simple-cache": "^1.0"
},
"repositories": [
{
Expand Down
5 changes: 3 additions & 2 deletions examples/no-framework/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@
use TheCodingMachine\GraphQLite\SchemaFactory;
use TheCodingMachine\GraphQLite\Context\Context;

use Symfony\Component\Cache\Simple\FilesystemCache;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Psr16Cache;
use Mouf\Picotainer\Picotainer;
use GraphQL\Utils\SchemaPrinter;
use App\Controllers\MyController;

require_once __DIR__ . '/vendor/autoload.php';

// $cache is any PSR-16 compatible cache.
$cache = new FilesystemCache();
$cache = new Psr16Cache(new FilesystemAdapter());;

// $container is any PSR-11 compatible container which has
// been populated with your controller classes.
Expand Down
2 changes: 1 addition & 1 deletion phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ parameters:
message: '#Unreachable statement - code above always terminates.#'
path: src/Http/WebonyxGraphqlMiddleware.php
-
message: '#Property TheCodingMachine\\GraphQLite\\Annotations\\Type::\$class \(class-string<object>\\|null\) does not accept string.#'
message: '#Property TheCodingMachine\\GraphQLite\\Annotations\\Type::\$class \(class-string<object>\|null\) does not accept string.#'
path: src/Annotations/Type.php
-
message: '#Method TheCodingMachine\\GraphQLite\\AnnotationReader::(getMethodAnnotations|getPropertyAnnotations)\(\) should return array<int, T of object> but returns array<object>.#'
Expand Down
43 changes: 43 additions & 0 deletions src/Cache/ClassBoundCacheContract.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?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;
}
13 changes: 13 additions & 0 deletions src/Cache/ClassBoundCacheContractInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?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. */
public function get(ReflectionClass $reflectionClass, callable $resolver, string $key = '', int|null $ttl = null): mixed;
}
7 changes: 7 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,11 @@ public function getCache(): CacheInterface
return $this->cache;
}

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

public function getInputTypeValidator(): InputTypeValidatorInterface|null
{
return $this->inputTypeValidator;
Expand Down
26 changes: 8 additions & 18 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 Down Expand Up @@ -66,23 +64,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
3 changes: 3 additions & 0 deletions src/Mappers/GlobTypeMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
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;
Expand Down Expand Up @@ -44,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 @@ -63,6 +65,7 @@ public function __construct(
$cache,
$globTTL,
$mapTTL,
$classBoundCacheContractFactory,
);
}

Expand Down
3 changes: 3 additions & 0 deletions src/Mappers/StaticClassListTypeMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
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;
Expand Down Expand Up @@ -45,6 +46,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 +66,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 @@ -38,6 +38,7 @@ public function create(FactoryContext $context): TypeMapperInterface
$context->getCache(),
$context->getGlobTTL(),
$context->getMapTTL(),
$context->getClassBoundCacheContractFactory(),
);
}
}
17 changes: 16 additions & 1 deletion 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 @@ -120,7 +121,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|null $classBoundCacheContractFactory = null)
{
$this->cacheNamespace = substr(md5(Versions::getVersion('thecodingmachine/graphqlite')), 0, 8);
}
Expand Down Expand Up @@ -259,6 +260,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 +443,7 @@ public function createSchema(): Schema
$recursiveTypeMapper,
$namespacedCache,
$this->globTTL,
classBoundCacheContractFactory: $this->classBoundCacheContractFactory,
));
}

Expand All @@ -447,6 +461,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 069d62a

Please sign in to comment.