emag-tech-labs/cache-bundle

此包已被废弃,不再维护。作者建议使用 emag-tech-labs/annotation-cache-bundle 包代替。

基于注解的对称容器内部服务缓存

安装数: 19,031

依赖者: 0

建议者: 0

安全: 0

星标: 18

关注者: 20

分支: 6

开放问题: 3

类型:symfony-bundle

6.0.2 2023-03-30 17:08 UTC

README

Packagist Version Build Status Total Downloads Latest Stable Version License Coverage Status

对称容器内部服务方法响应的注解缓存。

此包可以帮助您通过简单的注解或属性添加缓存。您可以将缓存存储在任何实现PSR-6:缓存接口的类中,无论是简单的数组还是redis/memcache存储。

工作原理

此包将扫描所有定义的服务中的所有方法,寻找缓存注解或属性(对于PHP 8+)。

对于找到缓存注解/属性的任何服务,它将创建一个代理类(使用ocramius/proxy-manager),该类扩展了服务类,包含CacheableClassTrait并覆盖具有缓存注解/属性的方法。

覆盖的方法包括调用getCached方法,该方法识别注解细节,获取键,获取Cache PSR-6实现,然后从缓存中获取结果。如果未找到具有生成的缓存键的数据,它将调用原始方法,然后将响应保存到指定的提供者。

此包有一个CompilerPass实现,将搜索并覆盖服务定义,使用上述过程中创建的代理类。

安装

使用Symfony Flex

通过使用 Symfony Flex 安装和配置AnnotationCacheBundle是Symfony中最简单的方法。

 composer require symfony/flex ^1.0
 composer config extra.symfony.allow-contrib true
 composer require emag-tech-labs/annotation-cache-bundle

Symfony Flex将自动注册和配置包。

不使用Symfony Flex

如果您的应用程序不使用Symfony Flex,您可以按照以下步骤手动配置包

步骤 1:下载包

打开命令行,进入您的项目目录,并执行以下命令以下载此包的最新稳定版本

composer require emag-tech-labs/annotation-cache-bundle

步骤 2:启用包

然后,通过将其添加到项目config/bundles.php文件中注册的包列表中,启用该包。

// config/bundles.php

return [
    // ...
    EmagTechLabs\AnnotationCacheBundle\AnnotationCacheBundle::class => ['all' => true],
];

步骤 3:配置

最简单的方法是将配置导出到configs/packages/emag_annotation_cache.yaml

bin/console config:dump-reference AnnotationCacheBundle
配置示例

您必须配置PSR6兼容的服务名称,这意味着它必须实现Psr\Cache\CacheItemPoolInterface

# app/config/services.yaml

services:
    cache.array:
        class: Symfony\Component\Cache\Adapter\ArrayAdapter
    cache.redis:
        class: Symfony\Component\Cache\Adapter\RedisAdapter
        arguments: ['@predis']
#configs/packages/emag_annotation_cache.yaml

# Annotation Cache Bundle
annotation_cache:
    provider: 
        default: cache.redis
        array: cache.array
    ignore_namespaces:
      - 'Symfony\\'
      - 'Doctrine\\'
    ignore_names:
      - legacy
      - type
      - required

用法

为要缓存的函数添加Cache注解。

注解参数

  • cache - 缓存前缀,字符串默认值: null(例如:'my_custom_prefix_')
  • key - 包含在缓存键哈希生成中的参数名称,字符串,用逗号分隔的参数名称默认值: ''(例如:'a,b')
  • ttl - 缓存在秒数,整数默认值: 600(例如:'3600')
  • reset - 如果缓存应该重置或不重置,布尔值默认值: false(例如:'true')
  • storage - 如果定义了多个提供者,可以指定使用哪个提供者,字符串默认值: 'default'(例如:'array')

使用Doctrine Annotations库定义的注解

use EmagTechLabs\AnnotationCacheBundle\Annotation\Cache;

/**
 * @Cache(cache="<put your prefix>", [key="<name of argument to include in cache key separated by comma>",  [ttl=600, [reset=true, [storage=default ]]]])
 */

示例

namespace AppCacheBundle\Service;

use EmagTechLabs\AnnotationCacheBundle\Annotation\Cache;

class AppService
{
    /**
     * @Cache(cache="app_high_cpu", ttl=60)
     *
     * @return int
     */
    public function getHighCPUOperation(): int
    {
        sleep(10); // 'Simulate a time consuming operation';
        return 20;
    }
}

使用PHP 8属性定义的注解

use EmagTechLabs\AnnotationCacheBundle\Annotation\Cache;

 #[Cache(cache:'<put your prefix>', key:'<name of argument to include in cache key separated by comma>', ttl:600, reset: true, storage: 'default')]

示例

namespace AppCacheBundle\Service;

use EmagTechLabs\AnnotationCacheBundle\Annotation\Cache;

class AppService
{
    #[Cache(cache:'app_high_cpu', ttl: 60)]
    public function getHighCPUOperation(): int
    {
        sleep(10); // 'Simulate a time consuming operation';
        return 20;
    }
}

用例

以下您可以找到两种使用此Bundle的方法

配置

# app/config/services.yaml

services:
    cache.array:
        class: Symfony\Component\Cache\Adapter\ArrayAdapter
    cache.redis:
        class: Symfony\Component\Cache\Adapter\RedisAdapter
        arguments: ['@predis']
#configs/packages/emag_annotation_cache.yaml

# Annotation Cache Bundle
annotation_cache:
    provider: 
        default: cache.array
        redis: cache.redis
    ignore_namespaces:
      - 'Symfony\\'

服务代码

此bundle可以用多种方式使用,以下展示了两种方式。

第一种情况是最常见的,您有一个执行多个耗时操作的函数,并希望将响应缓存到redis中,使用前缀(simple_time_consuming_operation_)和给定的时间(以下示例中的60s)进行缓存。这里的逻辑是先在redis中查找值,如果未找到,则执行实际的方法,获取结果并将其缓存以供将来使用,同时考虑在@Cache注解中传递的参数。

第二种情况可以用于在命令中生成缓存并使其预先加载,或者在某些事件触发时更新缓存,或者更新数据库中的信息。根据以下示例,您可以设置一个cron作业每3000秒运行一次,这样在缓存过期之前将重新创建缓存。因为我们使用相同的缓存前缀和键,当两个方法(getTimeConsumingOperationValueWithResetgetTimeConsumingOperationValue)传递相同的参数值时,生成的缓存键将是相同的,在这种情况下:time_consuming_operation_7fe49b314fb356bee76dbd3b8716b4d5ab5db600。这意味着两个方法都将写入(和读取)相同的缓存键。因为第二个方法将reset参数设置为true,所以对第二个方法的任何调用都将覆盖键time_consuming_operation_7fe49b314fb356bee76dbd3b8716b4d5ab5db600中的缓存值,以函数的新结果覆盖。

namespace AppCacheBundle\Service;

use EmagTechLabs\AnnotationCacheBundle\Annotation\Cache;

class AppService
{
    /**
     * @Cache(cache="simple_time_consuming_operation_", ttl=60, storage="redis")
     *
     * @param int $a
     * @param int $b
     * 
     * @return int
     */
    public function getSimpleTimeConsumingOperationValue(int $a, int $b): int
    {
        sleep(10); // 'Simulate a time consuming operation';
        return $a + $b;
    }
    
    #[Cache(cache:'time_consuming_operation_', key: 'a,b', ttl: 3600, storage: 'redis')]
    public function getTimeConsumingOperationValue(int $a, int $b): int
    {
        return $this->getTimeConsumingOperationValueWithReset($a, $b);
    }
    
    #[Cache(cache:'time_consuming_operation_', key: 'a,b', ttl: 3600, reset: true, storage: 'redis')]
    public function getTimeConsumingOperationValueWithReset(int $a, int $b): int
    {
        sleep(10); // 'Simulate a time consuming operation';
        return $a + $b;
    }
}

服务调用

// from controller
/** AppService $appService */
$appService->getTimeConsumingOperationValue(1, 2);

// from command
/** AppService $appService */
$appService->getTimeConsumingOperationValueWithReset(1, 2);

贡献

感谢您对贡献的兴趣!有许多方法可以为这个项目做出贡献。从这里开始。