Update caching solution
This commit is contained in:
parent
47778c187d
commit
af00264e92
|
|
@ -270,17 +270,11 @@ By default there is a global caching period set in `lib/config.js`, some sources
|
|||
- Save to cache:
|
||||
|
||||
```js
|
||||
ctx.cache.set((key: string), (value: string), (time: number), (persistent: boolean)); // time is the caching period in seconds. When persistent is set to true, the cache will refresh its expiry time upon every re-request (Under Redis this means the cache will never expire).
|
||||
ctx.cache.set((key: string), (value: string), (time: number)); // time is the caching period in seconds.
|
||||
```
|
||||
|
||||
- Access the cache:
|
||||
|
||||
::: tip tips
|
||||
|
||||
Since Redis caches with `persistent = true` will never expire, parameter `persistent` for `Get()` only has effect on LRU memory cache, it serves no purpose for Redis.
|
||||
|
||||
:::
|
||||
|
||||
```js
|
||||
const value = await ctx.cache.get((key: string));
|
||||
```
|
||||
|
|
@ -291,14 +285,14 @@ Given the update frequency is known, set the appropriate caching period to reuse
|
|||
|
||||
```js
|
||||
const key = 'daily' + story.id; // story.id is the unique identifier of each article
|
||||
ctx.cache.set(key, item.description, 24 * 60 * 60, true); // set the LRU memeroy caching period to 24 hours * 60 minutes * 60 seconds = 86,400 seconds = 1 day
|
||||
ctx.cache.set(key, item.description, 24 * 60 * 60); // set the caching period to 24 hours * 60 minutes * 60 seconds = 86,400 seconds = 1 day
|
||||
```
|
||||
|
||||
When the identical requests come in, reuse the cache:
|
||||
|
||||
```js
|
||||
const key = 'daily' + story.id;
|
||||
const value = await ctx.cache.get(key, true); // query the LRU memory cache to find the unique identifier
|
||||
const value = await ctx.cache.get(key); // query the cache to find the unique identifier
|
||||
if (value) {
|
||||
// return the cached data
|
||||
item.description = value; // assign the cached data
|
||||
|
|
|
|||
|
|
@ -267,17 +267,11 @@ sidebar: auto
|
|||
- 添加缓存:
|
||||
|
||||
```js
|
||||
ctx.cache.set((key: string), (value: string), (time: number), (persistent: boolean)); // time 为缓存时间。单位为秒。persistent 为 true 则为缓存自动延长过期时间 (Redis 下则为永不过期)。
|
||||
ctx.cache.set((key: string), (value: string), (time: number)); // time 为缓存时间。单位为秒。
|
||||
```
|
||||
|
||||
- 获取缓存:
|
||||
|
||||
::: tip 提示
|
||||
|
||||
由于 Redis 下 `persistent = true` 的缓存不会过期,`Get()` 下 `persistent` 参数仅适用于 LRU memory 缓存,对于 Redis 不会有任何效果。
|
||||
|
||||
:::
|
||||
|
||||
```js
|
||||
const value = await ctx.cache.get((key: string));
|
||||
```
|
||||
|
|
@ -288,14 +282,14 @@ const value = await ctx.cache.get((key: string));
|
|||
|
||||
```js
|
||||
const key = 'daily' + story.id; // story.id 为知乎日报返回的文章唯一识别符
|
||||
ctx.cache.set(key, item.description, 24 * 60 * 60, true); // 设置 LRU memory 缓存时间为 24小时 * 60分钟 * 60秒 = 86400秒 = 1天
|
||||
ctx.cache.set(key, item.description, 24 * 60 * 60); // 设置缓存时间为 24小时 * 60分钟 * 60秒 = 86400秒 = 1天
|
||||
```
|
||||
|
||||
当同样的请求被发起时,优先使用未过期的缓存:
|
||||
|
||||
```js
|
||||
const key = 'daily' + story.id;
|
||||
const value = await ctx.cache.get(key, true); // 从 LRU memory 缓存中查询是否已存在该文章唯一识别符
|
||||
const value = await ctx.cache.get(key); // 从缓存中查询是否已存在该文章唯一识别符
|
||||
if (value) {
|
||||
// 查询返回未过期缓存
|
||||
item.description = value; // 直接赋值
|
||||
|
|
|
|||
|
|
@ -94,11 +94,11 @@ if (config.cacheType === 'memory') {
|
|||
set: () => null,
|
||||
};
|
||||
}
|
||||
app.context.cache.tryGet = async function(key, getValueFunc, maxAge = 24 * 60 * 60, persistent = false) {
|
||||
let v = await this.get(key, persistent);
|
||||
app.context.cache.tryGet = async function(key, getValueFunc, maxAge = 24 * 60 * 60) {
|
||||
let v = await this.get(key);
|
||||
if (!v) {
|
||||
v = await getValueFunc();
|
||||
this.set(key, v, maxAge, persistent);
|
||||
this.set(key, v, maxAge);
|
||||
} else {
|
||||
let parsed;
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -15,28 +15,24 @@ module.exports = function(options = {}) {
|
|||
ignoreQuery = false,
|
||||
} = options;
|
||||
|
||||
const temporaryCache = new lru({
|
||||
const pageCache = new lru({
|
||||
maxAge: expire * 1000,
|
||||
max: maxLength,
|
||||
});
|
||||
|
||||
const persistentCache = new lru({
|
||||
const routeCache = new lru({
|
||||
maxAge: expire * 1000,
|
||||
max: maxLength,
|
||||
updateAgeOnGet: true,
|
||||
});
|
||||
|
||||
options.app.context.cache = {
|
||||
get: (key, persistent = false) => {
|
||||
get: (key) => {
|
||||
if (key) {
|
||||
if (persistent) {
|
||||
return persistentCache.get(key);
|
||||
} else {
|
||||
return temporaryCache.get(key);
|
||||
}
|
||||
return routeCache.get(key);
|
||||
}
|
||||
},
|
||||
set: (key, value, maxAge, persistent = false) => {
|
||||
set: (key, value, maxAge) => {
|
||||
if (!value || value === 'undefined') {
|
||||
value = '';
|
||||
}
|
||||
|
|
@ -44,11 +40,7 @@ module.exports = function(options = {}) {
|
|||
value = JSON.stringify(value);
|
||||
}
|
||||
if (key) {
|
||||
if (persistent) {
|
||||
return persistentCache.set(key, value, maxAge * 1000);
|
||||
} else {
|
||||
return temporaryCache.set(key, value, maxAge * 1000);
|
||||
}
|
||||
return routeCache.set(key, value, maxAge * 1000);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
@ -91,13 +83,13 @@ module.exports = function(options = {}) {
|
|||
*/
|
||||
async function getCache(ctx, key, tkey) {
|
||||
let type;
|
||||
const value = temporaryCache.get(key);
|
||||
const value = pageCache.get(key);
|
||||
|
||||
let ok = false;
|
||||
|
||||
if (value) {
|
||||
ctx.response.status = 200;
|
||||
type = temporaryCache.get(tkey) || 'text/html';
|
||||
type = pageCache.get(tkey) || 'text/html';
|
||||
// can happen if user specified return_buffers: true in redis options
|
||||
if (Buffer.isBuffer(type)) {
|
||||
type = type.toString();
|
||||
|
|
@ -130,7 +122,7 @@ module.exports = function(options = {}) {
|
|||
if (Buffer.byteLength(body) > maxLength) {
|
||||
return;
|
||||
}
|
||||
temporaryCache.set(key, body);
|
||||
pageCache.set(key, body);
|
||||
|
||||
await cacheType(ctx, tkey);
|
||||
}
|
||||
|
|
@ -141,7 +133,7 @@ module.exports = function(options = {}) {
|
|||
async function cacheType(ctx, tkey) {
|
||||
const type = ctx.response.headers['content-type'];
|
||||
if (type) {
|
||||
temporaryCache.set(tkey, type);
|
||||
pageCache.set(tkey, type);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -42,14 +42,18 @@ module.exports = function(options = {}) {
|
|||
});
|
||||
|
||||
options.app.context.cache = {
|
||||
/* eslint-disable no-unused-vars */
|
||||
get: async (key, persistent = false) => {
|
||||
/* eslint-enable no-unused-vars */
|
||||
get: async (key) => {
|
||||
if (key) {
|
||||
return await redisClient.get(key);
|
||||
const value = await redisClient.get(key);
|
||||
if (value) {
|
||||
let ttl = redisClient.ttl(key);
|
||||
ttl = ttl > expire ? ttl : expire * 2;
|
||||
await redisClient.setex(key, ttl, value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
},
|
||||
set: async (key, value, maxAge, persistent = false) => {
|
||||
set: async (key, value, maxAge) => {
|
||||
if (!value || value === 'undefined') {
|
||||
value = '';
|
||||
}
|
||||
|
|
@ -57,11 +61,7 @@ module.exports = function(options = {}) {
|
|||
value = JSON.stringify(value);
|
||||
}
|
||||
if (key) {
|
||||
if (persistent) {
|
||||
await redisClient.expire(key, value);
|
||||
} else {
|
||||
await redisClient.setex(key, maxAge, value);
|
||||
}
|
||||
await redisClient.setex(key, maxAge, value);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue