Skip to content

Commit

Permalink
feat(cache): can clear
Browse files Browse the repository at this point in the history
  • Loading branch information
jiawei397 committed Feb 14, 2022
1 parent d741e6b commit a010b51
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 6 deletions.
24 changes: 21 additions & 3 deletions src/decorators/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { isDebug } from "../utils.ts";

export type GetCacheKey = (...args: any[]) => string;

const META_CACHE_KEY = "meta:cache";

function transArgs(...args: any[]) {
return args.map((arg) => {
if (typeof arg === "object") {
Expand All @@ -13,6 +15,14 @@ function transArgs(...args: any[]) {
}).join("_");
}

const timeoutArr: number[] = [];
export function clearCacheTimeout() {
timeoutArr.forEach((t) => {
clearTimeout(t);
});
timeoutArr.length = 0;
}

/**
* Cache decorator
*/
Expand All @@ -30,7 +40,10 @@ export function Cache(
const key = getCacheKey
? getCacheKey.apply(this, args)
: transArgs(...args);
let cache: Record<string, any> = Reflect.getMetadata("cache", descriptor);
let cache: Record<string, any> = Reflect.getMetadata(
META_CACHE_KEY,
descriptor,
);
if (cache) {
if (cache[key] !== undefined) {
if (isDebug()) {
Expand All @@ -40,14 +53,19 @@ export function Cache(
}
} else {
cache = {};
Reflect.defineMetadata("cache", cache, descriptor);
Reflect.defineMetadata(META_CACHE_KEY, cache, descriptor);
const callback = () => {
Reflect.defineMetadata(META_CACHE_KEY, {}, descriptor);
};
addEventListener("clearCache_" + key, callback); // clear cache by `dispatchEvent(new CustomEvent("clearCache_xxx"));`
}
const result = originalMethod.apply(this, args);
cache[key] = result;
if (timeout >= 0) {
setTimeout(() => {
const st = setTimeout(() => {
cache[key] = undefined;
}, timeout);
timeoutArr.push(st);
}
Promise.resolve(result).catch(() => {
cache[key] = undefined;
Expand Down
32 changes: 29 additions & 3 deletions src/decorators/cache_test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// deno-lint-ignore-file require-await
import { assert, assertEquals, delay } from "../../test_deps.ts";
import { Cache } from "./cache.ts";
import { Cache, clearCacheTimeout } from "./cache.ts";

Deno.test("cache hit", async () => {
const callStacks: number[] = [];
Expand Down Expand Up @@ -47,7 +47,7 @@ Deno.test("cache hit", async () => {
assertEquals(callStacks, [1]);
await p6;

await delay(200);
clearCacheTimeout();
});

Deno.test("self key", async () => {
Expand Down Expand Up @@ -99,5 +99,31 @@ Deno.test("self key", async () => {
assertEquals(callStacks, [1, 2, 3, 4]);
assertEquals(await p4, await p6);

await delay(200);
clearCacheTimeout();
});

Deno.test("clearCache", async () => {
const callStacks: number[] = [];
const cacheKey = "test";
class A {
@Cache(1000 * 60 * 60, () => cacheKey)
method(id: number) {
callStacks.push(1);
return id;
}
}

const a = new A();
const p1 = a.method(1);
const p2 = a.method(1);
assert(p1 === p2);
assertEquals(callStacks, [1]);

dispatchEvent(new CustomEvent("clearCache_" + cacheKey));

const p3 = a.method(1);
assert(p3 === p1);
assertEquals(callStacks, [1, 1]);

clearCacheTimeout();
});

0 comments on commit a010b51

Please sign in to comment.