Demo

Caching ထည့်သွင်းခြင်း

Root module ပေါ်တွင် @Cache ဖြင့် cache ကို ကြေညာရပါသည် (in-memory သို့မဟုတ် env မှ Redis)။ @CacheClient ဖြင့် inject လုပ်ပြီး၊ လိုအပ်ပါက @CacheRoute / @CacheFn ဖြင့် HTTP route သို့မဟုတ် method ရလဒ်ကို cache လုပ်နိုင်ပါသည်။ အခြား plugin ၏ cache ကို ပြန်လည်အသုံးပြုပါ — ထပ်မံ မကြေညာရပါ။

ပန်းတိုင်နှင့် မည်သည့်အခါ အသုံးပြုမည်နည်း

ထပ်ခါတလဲလဲ ဖတ်ရှုမှု၊ session/token သိုလှောင်မှုနှင့် ကုန်ကျစရိတ်များသော တွက်ချက်မှုများအတွက် caching ကို အသုံးပြုပါ။ Client ကို ပိုင်ဆိုင်သော plugin ၏ root module ပေါ်တွင် တစ်ကြိမ်သာ ကြေညာပြီး၊ တူညီသော process အတွင်း နေရာမရွေး inject လုပ်နိုင်ပါသည် — အခြား plugin များအပါအဝင် ဖြစ်ပါသည်။

  • In-memory — process တစ်ခုတည်းအတွက်၊ ရိုးရှင်းသော TTL / checkperiod
  • Redis — instance အများအပြား မျှဝေအသုံးပြုနိုင်ပါသည်; host / port / password ကို env မှ ရယူပါ
  • Cross-plugin — ပိုင်ဆိုင်သူ၏ cache ကို inject လုပ်ပါ; တူညီသော @Cache ကို ထပ်မံ မကြေညာရပါ

1. လိုအပ်ချက်များ

Root @Module လိုအပ်ပါသည်။ Redis အတွက် PluginEnv / base .env မှ credentials များကို boot အချိန်တွင် ရယူနိုင်ရပါမည်။

  • Root @Module({ name: metadata.name, … }) ရှိပြီးသား ဖြစ်ရပါမည်
  • Redis — boot တွင် REDIS_HOST / REDIS_PORT / REDIS_PASSWORD (သို့မဟုတ် ရွေးထားသော env အမည်များ) ရရှိရပါမည်
  • အခြား plugin ၏ cache ကို သုံးမည်ဆိုပါက ပိုင်ဆိုင်သူကို pluginDependencies တွင် ထည့်သွင်းပါ
  • @Cache သည် @Module class ပေါ်တွင်သာ တပ်ရပါသည် — service သို့မဟုတ် controller ပေါ်တွင် မဟုတ်ပါ

2. Root module ပေါ်တွင် @Cache ကြေညာခြင်း

Cache အများအပြား ဖွင့်မည်ဆိုပါက ထူးခြားသော name ပေးရပါသည်။ Module class တစ်ခုပေါ်တွင် @Cache အများအပြား တပ်ခွင့်ပြုပါသည်။

  • type — "in-memory" သို့မဟုတ် Redis options (host, port, password, …)
  • name — optional client id; @Cache အများအပြား ကြေညာလျှင် လိုအပ်ပါသည်
  • ပိုင်ဆိုင်သူသည် loading plugin ဖြစ်ပါသည် — consumer က ထို plugin ၏ metadata.name ဖြင့် ညွှန်ရပါသည်
TSXdeclare caches
1import { Cache, Module } from "@quan-erp/shared-backend-core"; 2import metadata from "../../module.metadata.json" with { type: "json" }; 3 4@Cache({ 5 name: "publisher", 6 type: "in-memory", 7 checkperiod: 1000, 8}) 9@Cache({ 10 name: "session", 11 type: "redis", 12 host: process.env.REDIS_HOST, 13 port: Number(process.env.REDIS_PORT ?? 6379), 14 password: process.env.REDIS_PASSWORD, 15}) 16@Module({ 17 name: metadata.name, 18 providers: [...], 19 controllers: [...], 20}) 21export class MyPluginModule {}

3. @CacheClient ဖြင့် inject လုပ်ခြင်း

Service property ပေါ်တွင် ICache ကို inject လုပ်ရပါသည်။ ပထမ argument သည် cache ကို ပိုင်ဆိုင်သော plugin ဖြစ်ပြီး၊ ဒုတိယသည် optional client name ဖြစ်ပါသည်။

  • metadata.name — ဤ plugin ၏ ကိုယ်ပိုင် cache (အများအပြားရှိလျှင် name ထည့်ပါ)
  • "other-plugin" — အခြား plugin က ဖန်တီးထားသော cache
  • CacheManager.DEFAULT_PLUGIN — သက်ဆိုင်ပါက core / shared default cache ပိုင်ဆိုင်သူ
TSXinject
1import { 2 CacheClient, 3 Service, 4} from "@quan-erp/shared-backend-core"; 5import type { ICache } from "@quan-erp/shared-backend-core"; 6import metadata from "../../module.metadata.json" with { type: "json" }; 7 8@Service() 9export class SessionService { 10 @CacheClient(metadata.name, "session") 11 private session: ICache; 12 13 async getToken(userId: string) { 14 return this.session.get(`token:${userId}`); 15 } 16}

4. Route နှင့် method helpers

Helper များကို ပိုင်ဆိုင်သော @Cache နှင့် တူညီသော plugin + name သို့ ညွှန်ရပါသည်။ Write လုပ်ခြင်းက cached read ကို invalidate လုပ်ပါက delete helper များကို အသုံးပြုပါ။

  • @CacheRoute / @DeleteCacheRoute — HTTP response cache; key သည် string သို့မဟုတ် (req) => string ဖြစ်နိုင်ပါသည်
  • @CacheFn / @DeleteCacheFn — method ရလဒ် cache; key သည် (...args) => string ဖြစ်ပါသည်
  • plugin + name သည် ပိုင်ဆိုင်သော @Cache နှင့် ကိုက်ညီရပါမည် (အခြား plugin ၏ client အပါအဝင်)
TSroute cache
1@CacheRoute({ 2 key: (req) => `orders:${req.query.status ?? "all"}`, 3 plugin: metadata.name, 4 name: "session", 5}) 6@Get("/orders") 7list() { /* … */ }
TSmethod cache
1@CacheFn({ 2 key: (id: number) => `order:${id}`, 3 plugin: metadata.name, 4 name: "session", 5}) 6async findOne(id: number) { /* … */ }

5. Cross-plugin ပြန်လည်အသုံးပြုခြင်း

Cache များသည် ပိုင်ဆိုင်သော plugin (+ optional name) ဖြင့် process-wide registry တွင် ရှိပါသည်။ Consumer သည် ထို client အတွက် @Cache ကို ပြန်မကြေညာဘဲ၊ ပိုင်ဆိုင်သူ၏ cache ကို inject လုပ်ပြီး helper များကို တူညီသော plugin + name သို့ ညွှန်ရပါသည်။

  • ပိုင်ဆိုင်သူ — @Cache({ name, … }) ကြေညာပြီး အရင် boot လုပ်ရပါသည် (pluginDependencies)
  • Consumer — @CacheClient("owner-plugin", "cache-name")
  • Route / method helpers — တူညီသော ပိုင်ဆိုင်သူ plugin + name
  • Consumer တိုင်းတွင် တူညီသော @Cache ကို ထပ်မံ မကြေညာရပါ
TSconsumer inject
1@Service() 2export class ReportService { 3 // "warehouse" plugin declared @Cache({ name: "replica", ... }) 4 @CacheClient("warehouse", "replica") 5 private replica: ICache; 6}

6. စစ်ဆေးခြင်း

  • Plugin boot လုပ်ရာတွင် cache / Redis connection အမှား မရှိရပါ
  • Inject လုပ်ထားသော ICache ၏ get / set / del သည် မျှော်မှန်းအတိုင်း အလုပ်လုပ်ရပါသည်
  • Cached route များသည် invalidate မလုပ်မီ တူညီသော payload ပြန်ပေးရပါသည်
  • @DeleteCacheRoute / @DeleteCacheFn က ရည်ရွယ်ထားသော key များကို ရှင်းလင်းရပါသည်

အဖြစ်များသော အမှားများ

  • @Cache ကို service သို့မဟုတ် controller ပေါ်တွင် တပ်ခြင်း — root @Module ပေါ်တွင်သာ တပ်ရပါသည်
  • Cache အများအပြား ကြေညာထားပါက name မပေးခြင်း
  • Redis credentials ကို hardcode လုပ်ခြင်း — env ကို အသုံးပြုရပါသည်
  • Consumer တွင် @Cache ထပ်မံ ကြေညာခြင်း — @CacheClient ကို သုံးရပါသည်
  • @CacheClient နှင့် @CacheRoute / @CacheFn ၏ plugin + name မကိုက်ညီခြင်း
  • pluginDependencies မေ့ခြင်း — ပိုင်ဆိုင်သူက consumer နောက်မှ load ဖြစ်သွားပါသည်