UNPKG

koatty_cacheable

Version:
235 lines (176 loc) 6.27 kB
# koatty_cacheable Cacheable plugin for Koatty. Koatty框架的 CacheAble, CacheEvict 缓存装饰器插件,提供方法级别的缓存功能。 ## 特性 - 🚀 **简单易用**: 通过装饰器轻松添加缓存功能 - 🔄 **自动缓存**: `@CacheAble` 装饰器自动缓存方法返回值 - 🗑️ **智能清除**: `@CacheEvict` 装饰器智能清除相关缓存 - ⚡ **延迟双删**: 支持延迟双删策略,解决缓存一致性问题 - 🔧 **多后端支持**: 支持 Memory 和 Redis 缓存后端 - 🎯 **参数化缓存**: 支持基于方法参数的缓存键生成 - 🛡️ **类型安全**: 完整的 TypeScript 支持 - 📦 **插件化设计**: 遵循 Koatty 插件标准,统一管理 ## 安装 ```bash npm install koatty_cacheable ``` ## 配置 ### 1. Generate Plugin Template Use Koatty CLI to generate the plugin template: ```bash kt plugin Cacheable ``` Create `src/plugin/Cacheable.ts`: ```typescript import { Plugin, IPlugin, App } from "koatty"; import { KoattyCache } from "koatty_cacheable"; @Plugin() export class Cacheable implements IPlugin { run(options: any, app: App) { return KoattyCache(options, app); } } ``` ### 2. Configure Plugin Update `src/config/plugin.ts`: ```typescript export default { list: ["Cacheable"], // Plugin loading order config: { Cacheable: { cacheTimeout: 300, // 默认缓存过期时间(秒) delayedDoubleDeletion: true, // 默认启用延迟双删策略 redisConfig: { host: "127.0.0.1", port: 6379, password: "", db: 0, keyPrefix: "koatty:cache:" } } } }; ``` ## 使用方法 ### 基本用法 ```typescript import { CacheAble, CacheEvict, GetCacheStore } from "koatty_cacheable"; import { Component } from "koatty_container"; @Component() export class UserService { // 自动缓存方法返回值 @CacheAble("userCache", { params: ["id"], // 使用 id 参数作为缓存键的一部分 timeout: 300 // 缓存过期时间(秒),默认使用插件配置的 cacheTimeout }) async getUserById(id: string): Promise<User> { // 数据库查询逻辑 return await this.userRepository.findById(id); } // 自动清除相关缓存 @CacheEvict("userCache", { params: ["id"], // 使用 id 参数定位要清除的缓存 delayedDoubleDeletion: true // 启用延迟双删策略,默认使用插件配置的 delayedDoubleDeletion }) async updateUser(id: string, userData: Partial<User>): Promise<User> { // 更新用户数据 const updatedUser = await this.userRepository.update(id, userData); return updatedUser; } // 手动操作缓存 async customCacheOperation() { const store = await GetCacheStore(this.app); // 设置缓存 await store.set("custom:key", "value", 60); // 获取缓存 const value = await store.get("custom:key"); // 删除缓存 await store.del("custom:key"); } } ``` ### 高级用法 ```typescript import { Component } from "koatty_container"; @Component() export class ProductService { // 无参数缓存 @CacheAble("productStats") async getProductStats(): Promise<ProductStats> { return await this.calculateStats(); } // 多参数缓存 @CacheAble("productSearch", { params: ["category", "keyword"], timeout: 600 // 覆盖插件配置的默认时间 }) async searchProducts(category: string, keyword: string, page: number = 1): Promise<Product[]> { return await this.productRepository.search(category, keyword, page); } // 立即清除缓存(不使用延迟双删) @CacheEvict("productSearch", { params: ["category"], delayedDoubleDeletion: false // 覆盖插件配置的默认策略 }) async updateProductCategory(category: string, updates: any): Promise<void> { await this.productRepository.updateCategory(category, updates); } } ``` ## API 文档 ### @CacheAble(cacheName, options?) 自动缓存装饰器,缓存方法的返回值。 **参数:** - `cacheName: string` - 缓存名称 - `options?: CacheAbleOpt` - 缓存选项 - `params?: string[]` - 用作缓存键的参数名数组 - `timeout?: number` - 缓存过期时间(秒),默认 300 ### @CacheEvict(cacheName, options?) 自动清除缓存装饰器,在方法执行后清除相关缓存。 **参数:** - `cacheName: string` - 要清除的缓存名称 - `options?: CacheEvictOpt` - 清除选项 - `params?: string[]` - 用于定位缓存的参数名数组 - `delayedDoubleDeletion?: boolean` - 是否启用延迟双删策略,默认 true ### GetCacheStore(app?) 获取缓存存储实例。 **参数:** - `app?: Application` - Koatty 应用实例 **返回:** `Promise<CacheStore>` ## 缓存键生成规则 缓存键按以下格式生成: ``` {cacheName}:{paramName1}:{paramValue1}:{paramName2}:{paramValue2}... ``` 例如: - `@CacheAble("user", {params: ["id"]})` + `getUserById("123")` → `user:id:123` - 当缓存键长度超过 128 字符时,会自动使用 murmur hash 进行压缩 ## 延迟双删策略 延迟双删是一种解决缓存一致性问题的策略: 1. 立即删除缓存 2. 执行数据更新操作 3. 延迟 5 秒后再次删除缓存 这样可以避免在并发场景下出现脏数据。 ## 配置优先级 配置项的优先级从高到低: 1. **装饰器配置**: 直接在 `@CacheAble` 或 `@CacheEvict` 中指定的选项 2. **插件配置**: 在 `src/config/plugin.ts` 中配置的 `Cacheable` 插件选项 3. **默认值**: 系统内置的默认配置 例如: ```typescript // 插件配置 Cacheable: { cacheTimeout: 300, delayedDoubleDeletion: true } // 装饰器配置会覆盖插件配置 @CacheAble("user", { timeout: 600 // 使用 600 秒而不是插件配置的 300 秒 }) ``` ## 注意事项 1. 缓存的数据会自动进行 JSON 序列化/反序列化 2. 如果缓存服务不可用,方法会正常执行,不会抛出错误 3. 插件会在应用启动时自动注入缓存功能到所有使用装饰器的方法 ## 许可证 BSD-3-Clause