Adds skipCacheResults to annotations of hyperf/cache (#5983)

Co-authored-by: 李铭昕 <715557344@qq.com>
This commit is contained in:
Deeka Wong 2023-07-28 23:26:37 +08:00 committed by GitHub
parent 4803bf4049
commit 329a04ad24
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 115 additions and 22 deletions

View File

@ -33,6 +33,7 @@
- [#5930](https://github.com/hyperf/hyperf/pull/5930) [#5934](https://github.com/hyperf/hyperf/pull/5934) Added `AsCommand` annotation and `ClosureCommand` support.
- [#5950](https://github.com/hyperf/hyperf/pull/5950) Added `Job::setMaxAttempts` method and `dispatch` helper function for `hyperf/async-queue`.
- [#5967](https://github.com/hyperf/hyperf/pull/5967) Added component `hyperf/migration-generator` which used to generate migrations from databases.
- [#5983](https://github.com/hyperf/hyperf/pull/5983) Added `skipCacheResults` to annotations of `hyperf/cache`.
## Optimized

View File

@ -32,7 +32,8 @@ class CacheAhead extends AbstractAnnotation
public int $lockSeconds = 10,
public int $offset = 0,
public string $group = 'default',
public bool $collect = false
public bool $collect = false,
public array $skipCacheResults = []
) {
}

View File

@ -25,7 +25,8 @@ class CachePut extends AbstractAnnotation
public ?string $value = null,
public ?int $ttl = null,
public int $offset = 0,
public string $group = 'default'
public string $group = 'default',
public array $skipCacheResults = []
) {
}
}

View File

@ -29,7 +29,8 @@ class Cacheable extends AbstractAnnotation
public ?string $listener = null,
public int $offset = 0,
public string $group = 'default',
public bool $collect = false
public bool $collect = false,
public array $skipCacheResults = []
) {
}

View File

@ -24,7 +24,8 @@ class FailCache extends AbstractAnnotation
public ?string $value = null,
public ?int $ttl = null,
public ?string $listener = null,
public string $group = 'default'
public string $group = 'default',
public array $skipCacheResults = []
) {
}

View File

@ -54,17 +54,19 @@ class CacheAheadAspect extends AbstractAspect
$result = $proceedingJoinPoint->process();
$driver->set(
$key,
[
'expired_time' => $now + $annotation->ttl - $annotation->aheadSeconds,
'data' => $result,
],
$ttl
);
if (! in_array($result, $annotation->skipCacheResults, true)) {
$driver->set(
$key,
[
'expired_time' => $now + $annotation->ttl - $annotation->aheadSeconds,
'data' => $result,
],
$ttl
);
if ($driver instanceof KeyCollectorInterface && $annotation instanceof CacheAhead && $annotation->collect) {
$driver->addKey($annotation->prefix . 'MEMBERS', $key);
if ($driver instanceof KeyCollectorInterface && $annotation instanceof CacheAhead && $annotation->collect) {
$driver->addKey($annotation->prefix . 'MEMBERS', $key);
}
}
return $result;

View File

@ -33,13 +33,16 @@ class CachePutAspect extends AbstractAspect
$method = $proceedingJoinPoint->methodName;
$arguments = $proceedingJoinPoint->arguments['keys'];
[$key, $ttl, $group] = $this->annotationManager->getCachePutValue($className, $method, $arguments);
/** @var CachePut $annotation */
[$key, $ttl, $group, $annotation] = $this->annotationManager->getCachePutValue($className, $method, $arguments);
$driver = $this->manager->getDriver($group);
$result = $proceedingJoinPoint->process();
$driver->set($key, $result, $ttl);
if (! in_array($result, $annotation->skipCacheResults, true)) {
$driver->set($key, $result, $ttl);
}
return $result;
}

View File

@ -47,9 +47,12 @@ class CacheableAspect extends AbstractAspect
$result = $proceedingJoinPoint->process();
$driver->set($key, $result, $ttl);
if ($driver instanceof KeyCollectorInterface && $annotation instanceof Cacheable && $annotation->collect) {
$driver->addKey($annotation->prefix . 'MEMBERS', $key);
if (! in_array($result, $annotation->skipCacheResults, true)) {
$driver->set($key, $result, $ttl);
if ($driver instanceof KeyCollectorInterface && $annotation instanceof Cacheable && $annotation->collect) {
$driver->addKey($annotation->prefix . 'MEMBERS', $key);
}
}
return $result;

View File

@ -37,13 +37,17 @@ class FailCacheAspect extends AbstractAspect
$method = $proceedingJoinPoint->methodName;
$arguments = $proceedingJoinPoint->arguments['keys'];
[$key, $ttl, $group] = $this->annotationManager->getFailCacheValue($className, $method, $arguments);
/** @var FailCache $annotation */
[$key, $ttl, $group, $annotation] = $this->annotationManager->getFailCacheValue($className, $method, $arguments);
$driver = $this->manager->getDriver($group);
try {
$result = $proceedingJoinPoint->process();
$driver->set($key, $result, $ttl);
if (! in_array($result, $annotation->skipCacheResults, true)) {
$driver->set($key, $result, $ttl);
}
} catch (Throwable $throwable) {
[$has, $result] = $driver->fetch($key);
if (! $has) {

View File

@ -11,8 +11,10 @@ declare(strict_types=1);
*/
namespace HyperfTest\Cache\Cases;
use Hyperf\Cache\Annotation\Cacheable;
use Hyperf\Cache\Annotation\CacheAhead;
use Hyperf\Cache\AnnotationManager;
use Hyperf\Cache\Aspect\CacheableAspect;
use Hyperf\Cache\Aspect\CacheAheadAspect;
use Hyperf\Cache\CacheManager;
use Hyperf\Di\Aop\ProceedingJoinPoint;
@ -33,6 +35,78 @@ class AspectTest extends TestCase
Mockery::close();
}
public function testCacheableAspect()
{
$container = ContainerStub::getContainer();
$manager = Mockery::mock(AnnotationManager::class);
$manager->shouldReceive('getCacheableValue')->andReturn(['test', 3600, 'default', new Cacheable('test', '1', 3600)]);
$redis = $container->get(CacheManager::class)->getDriver();
$redis->delete('test');
$aspect = new CacheableAspect($container->get(CacheManager::class), $manager);
$point = new ProceedingJoinPoint(fn () => uniqid(), 'test', 'test', ['keys' => []]);
$point->pipe = static function (ProceedingJoinPoint $res) {
return $res->processOriginalMethod();
};
$id = $aspect->process($point);
$point->pipe = static function (ProceedingJoinPoint $res) {
return $res->processOriginalMethod();
};
$res = $aspect->process($point);
$this->assertSame($id, $res);
}
public function testCacheableAspectWithSkipCacheResults()
{
$container = ContainerStub::getContainer();
$manager = Mockery::mock(AnnotationManager::class);
$manager->shouldReceive('getCacheableValue')->andReturn(['test', 3600, 'default', new Cacheable('test', '1', 3600)]);
$redis = $container->get(CacheManager::class)->getDriver();
$redis->delete('test');
$aspect = new CacheableAspect($container->get(CacheManager::class), $manager);
$point = new ProceedingJoinPoint(fn () => null, 'test', 'test', ['keys' => []]);
$point->pipe = static function (ProceedingJoinPoint $res) {
return $res->processOriginalMethod();
};
$res = $aspect->process($point);
$this->assertNull($res);
$this->assertTrue($redis->has('test'));
$this->assertNull($redis->get('test'));
$point->pipe = static function (ProceedingJoinPoint $res) {
return $res->processOriginalMethod();
};
$res = $aspect->process($point);
$this->assertNull($res);
$manager = Mockery::mock(AnnotationManager::class);
$manager->shouldReceive('getCacheableValue')->andReturn(['test', 3600, 'default', new Cacheable('test', '1', 3600, skipCacheResults: [null])]);
$redis = $container->get(CacheManager::class)->getDriver();
$redis->delete('test');
$aspect = new CacheableAspect($container->get(CacheManager::class), $manager);
$point = new ProceedingJoinPoint(fn () => null, 'test', 'test', ['keys' => []]);
$point->pipe = static function (ProceedingJoinPoint $res) {
return $res->processOriginalMethod();
};
$res = $aspect->process($point);
$this->assertNull($res);
$this->assertFalse($redis->has('test'));
$point->pipe = static function (ProceedingJoinPoint $res) {
return 0;
};
$res = $aspect->process($point);
$this->assertSame(0, $res);
$this->assertTrue($redis->has('test'));
}
public function testCacheAheadAspect()
{
$container = ContainerStub::getContainer();
@ -46,7 +120,9 @@ class AspectTest extends TestCase
return uniqid();
};
$point = new ProceedingJoinPoint($closure, 'test', 'test', ['keys' => []]);
$point->pipe = static function (ProceedingJoinPoint $res) {return uniqid(); };
$point->pipe = static function (ProceedingJoinPoint $res) {
return uniqid();
};
$redis->delete('test:lock');
$id = $aspect->process($point);