更换缓存到midway官方最新

This commit is contained in:
cool 2024-03-06 14:40:45 +08:00
parent ea9d43bbce
commit 0b4546e965
6 changed files with 184 additions and 175 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@cool-midway/core", "name": "@cool-midway/core",
"version": "7.1.4", "version": "7.1.6",
"description": "", "description": "",
"main": "dist/index.js", "main": "dist/index.js",
"typings": "index.d.ts", "typings": "index.d.ts",
@ -46,7 +46,9 @@
"typescript": "~4.9.4" "typescript": "~4.9.4"
}, },
"dependencies": { "dependencies": {
"@midwayjs/cache": "^3.9.0", "@cool-midway/cache-manager-fs-hash": "^7.0.0",
"@midwayjs/cache": "^3.14.0",
"@midwayjs/cache-manager": "^3.15.0",
"axios": "^1.6.5", "axios": "^1.6.5",
"decompress": "^4.2.1", "decompress": "^4.2.1",
"download": "^8.0.0", "download": "^8.0.0",

View File

@ -18,13 +18,13 @@ import { CoolModuleConfig } from "./module/config";
import { CoolModuleImport } from "./module/import"; import { CoolModuleImport } from "./module/import";
import { CoolEventManager } from "./event"; import { CoolEventManager } from "./event";
import { CoolEps } from "./rest/eps"; import { CoolEps } from "./rest/eps";
import { CacheManager } from "@midwayjs/cache";
import * as cache from "@midwayjs/cache";
import { CoolDecorator } from "./decorator"; import { CoolDecorator } from "./decorator";
import * as cache from "@midwayjs/cache-manager";
import * as _cache from "@midwayjs/cache";
@Configuration({ @Configuration({
namespace: "cool", namespace: "cool",
imports: [cache], imports: [_cache, cache],
importConfigs: [ importConfigs: [
{ {
default: DefaultConfig, default: DefaultConfig,
@ -59,7 +59,7 @@ export class CoolConfiguration implements ILifeCycle {
const eps: CoolEps = await container.getAsync(CoolEps); const eps: CoolEps = await container.getAsync(CoolEps);
eps.init(); eps.init();
// 缓存设置为全局 // 缓存设置为全局
global["COOL-CACHE"] = await container.getAsync(CacheManager); // global["COOL-CACHE"] = await container.getAsync(CacheManager);
// 清除 location // 清除 location
setTimeout(() => { setTimeout(() => {
location.clean(); location.clean();

View File

@ -1,8 +1,9 @@
import { COOL_CACHE } from "./cache"; import { COOL_CACHE } from "./cache";
import { CacheManager } from "@midwayjs/cache"; import { CachingFactory, MidwayCache } from "@midwayjs/cache-manager";
import { import {
Init, Init,
Inject, Inject,
InjectClient,
JoinPoint, JoinPoint,
MidwayDecoratorService, MidwayDecoratorService,
Provide, Provide,
@ -27,8 +28,8 @@ export class CoolDecorator {
@Inject() @Inject()
decoratorService: MidwayDecoratorService; decoratorService: MidwayDecoratorService;
@Inject() @InjectClient(CachingFactory, "default")
cacheManager: CacheManager; midwayCache: MidwayCache;
@Inject() @Inject()
coolUrlTagData: CoolUrlTagData; coolUrlTagData: CoolUrlTagData;
@ -56,15 +57,17 @@ export class CoolDecorator {
JSON.stringify(joinPoint.args) JSON.stringify(joinPoint.args)
); );
// 缓存有数据就返回 // 缓存有数据就返回
let data: any = await this.cacheManager.get(key); let data: any = await this.midwayCache.get(key);
if (data) { if (data) {
return JSON.parse(data); return JSON.parse(data);
} else { } else {
// 执行原始方法 // 执行原始方法
data = await joinPoint.proceed(...joinPoint.args); data = await joinPoint.proceed(...joinPoint.args);
await this.cacheManager.set(key, JSON.stringify(data), { await this.midwayCache.set(
ttl: options.metadata, key,
}); JSON.stringify(data),
options.metadata
);
} }
return data; return data;
}, },

View File

@ -7,6 +7,9 @@ export * from "./exception/base";
export * from "./exception/comm"; export * from "./exception/comm";
export * from "./exception/validate"; export * from "./exception/validate";
// cache
export * from "./cache/store";
// entity // entity
export * from "./entity/base"; export * from "./entity/base";
export * from "./entity/typeorm"; export * from "./entity/typeorm";

View File

@ -1,6 +1,6 @@
{ {
"name": "@cool-midway/core", "name": "@cool-midway/core",
"version": "7.1.4", "version": "7.1.6",
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"typings": "index.d.ts", "typings": "index.d.ts",
@ -44,7 +44,9 @@
"typescript": "~4.9.4" "typescript": "~4.9.4"
}, },
"dependencies": { "dependencies": {
"@midwayjs/cache": "^3.9.0", "@midwayjs/cache": "^3.14.0",
"@midwayjs/cache-manager": "^3.15.0",
"@cool-midway/cache-manager-fs-hash": "^7.0.0",
"axios": "^1.6.5", "axios": "^1.6.5",
"decompress": "^4.2.1", "decompress": "^4.2.1",
"download": "^8.0.0", "download": "^8.0.0",

View File

@ -1,11 +1,10 @@
const fs = require('fs'); const fs = require("fs");
const crypto = require('crypto'); const crypto = require("crypto");
const path = require('path'); const path = require("path");
const promisify = require('util').promisify; const promisify = require("util").promisify;
const lockFile = require('lockfile'); const lockFile = require("lockfile");
const jsonFileStore = require('./json-file-store'); const jsonFileStore = require("./json-file-store");
const wrapCallback = require('./wrap-callback'); const wrapCallback = require("./wrap-callback");
/** /**
* construction of the disk storage * construction of the disk storage
@ -18,31 +17,32 @@ const wrapCallback = require('./wrap-callback');
* @returns {DiskStore} * @returns {DiskStore}
*/ */
exports.create = function (args) { exports.create = function (args) {
return new DiskStore(args && args.options ? args.options : args); return new DiskStore(args && args.options ? args.options : args);
}; };
function DiskStore(options) { function DiskStore(options) {
options = options || {}; options = options || {};
this.options = { this.options = {
path: options.path || './cache', /* path for cached files */ path: options.path || "./cache" /* path for cached files */,
ttl: options.ttl, /* time before expiring in seconds */ ttl: options.ttl /* time before expiring in seconds */,
maxsize: options.maxsize || Infinity, /* max size in bytes on disk */ maxsize: options.maxsize || Infinity /* max size in bytes on disk */,
subdirs: options.subdirs || false, subdirs: options.subdirs || false,
zip: options.zip || false, zip: options.zip || false,
lockFile: { //check lock at 0ms 50ms 100ms ... 400ms 1400ms 1450ms... up to 10 seconds, after that just asume the lock is staled lockFile: {
wait: 400, //check lock at 0ms 50ms 100ms ... 400ms 1400ms 1450ms... up to 10 seconds, after that just asume the lock is staled
pollPeriod: 50, wait: 400,
stale: 10 * 1000, pollPeriod: 50,
retries: 10, stale: 10 * 1000,
retryWait: 600, retries: 10,
} retryWait: 600,
}; },
};
// check storage directory for existence (or create it) // check storage directory for existence (or create it)
if (!fs.existsSync(this.options.path)) { if (!fs.existsSync(this.options.path)) {
fs.mkdirSync(this.options.path); fs.mkdirSync(this.options.path);
} }
} }
/** /**
@ -55,78 +55,77 @@ function DiskStore(options) {
* @returns {Promise} * @returns {Promise}
*/ */
DiskStore.prototype.set = wrapCallback(async function (key, val, options) { DiskStore.prototype.set = wrapCallback(async function (key, val, options) {
key = key + ''; key = key + "";
const filePath = this._getFilePathByKey(key); const filePath = this._getFilePathByKey(key);
const ttl = (options && (options.ttl >= 0)) ? +options.ttl : this.options.ttl; const ttl = options && options.ttl >= 0 ? +options.ttl : this.options.ttl;
const data = { const data = {
key: key, key: key,
val: val, val: val,
}; };
if(ttl>0){ if (ttl > 0) {
data.expireTime = Date.now() + ttl * 1000; data.expireTime = Date.now() + ttl * 1000;
} }
if (this.options.subdirs) {
//check if subdir exists or create it
const dir = path.dirname(filePath);
await promisify(fs.access)(dir, fs.constants.W_OK).catch(function () {
return promisify(fs.mkdir)(dir).catch((err) => {
if (err.code !== "EEXIST") throw err;
});
});
}
if (this.options.subdirs) { try {
//check if subdir exists or create it await this._lock(filePath);
const dir = path.dirname(filePath); await jsonFileStore.write(filePath, data, this.options);
await promisify(fs.access)(dir, fs.constants.W_OK).catch(function () { } catch (err) {
return promisify(fs.mkdir)(dir).catch(err => { throw err;
if (err.code !== 'EEXIST') throw err; } finally {
}); await this._unlock(filePath);
}); }
}
try {
await this._lock(filePath);
await jsonFileStore.write(filePath, data, this.options);
} catch (err) {
throw err;
} finally {
await this._unlock(filePath);
}
}); });
DiskStore.prototype._readFile = async function (key) { DiskStore.prototype._readFile = async function (key) {
key = key + ''; key = key + "";
const filePath = this._getFilePathByKey(key); const filePath = this._getFilePathByKey(key);
try { try {
const data = await jsonFileStore.read(filePath, this.options).catch(async (err) => { const data = await jsonFileStore
if (err.code === 'ENOENT') { .read(filePath, this.options)
throw err; .catch(async (err) => {
} if (err.code === "ENOENT") {
//maybe the file is currently written to, lets lock it and read again throw err;
try {
await this._lock(filePath);
return await jsonFileStore.read(filePath, this.options);
} catch (err2) {
throw err2;
} finally {
await this._unlock(filePath);
}
});
if (data.expireTime <= Date.now()) {
//cache expired
this.del(key).catch(() => 0 /* ignore */);
return undefined;
} }
if (data.key !== key) { //maybe the file is currently written to, lets lock it and read again
//hash collision try {
return undefined; await this._lock(filePath);
} return await jsonFileStore.read(filePath, this.options);
return data; } catch (err2) {
throw err2;
} catch (err) { } finally {
//file does not exist lets return a cache miss await this._unlock(filePath);
if (err.code === 'ENOENT') {
return undefined;
} else {
throw err;
} }
});
if (data.expireTime <= Date.now()) {
//cache expired
this.del(key).catch(() => 0 /* ignore */);
return undefined;
} }
if (data.key !== key) {
//hash collision
return undefined;
}
return data;
} catch (err) {
//file does not exist lets return a cache miss
if (err.code === "ENOENT") {
return undefined;
} else {
throw err;
}
}
}; };
/** /**
@ -136,12 +135,12 @@ DiskStore.prototype._readFile = async function (key) {
* @returns {Promise} * @returns {Promise}
*/ */
DiskStore.prototype.get = wrapCallback(async function (key) { DiskStore.prototype.get = wrapCallback(async function (key) {
const data = await this._readFile(key); const data = await this._readFile(key);
if (data) { if (data) {
return data.val; return data.val;
} else { } else {
return data; return data;
} }
}); });
/** /**
@ -151,68 +150,68 @@ DiskStore.prototype.get = wrapCallback(async function (key) {
* @returns {Promise} * @returns {Promise}
*/ */
DiskStore.prototype.ttl = wrapCallback(async function (key) { DiskStore.prototype.ttl = wrapCallback(async function (key) {
const data = await this._readFile(key); const data = await this._readFile(key);
if (data) { if (data) {
return (data.expireTime - Date.now()) / 1000; return (data.expireTime - Date.now()) / 1000;
} else { } else {
return 0; return 0;
} }
}); });
/** /**
* delete entry from cache * delete entry from cache
*/ */
DiskStore.prototype.del = wrapCallback(async function (key) { DiskStore.prototype.del = wrapCallback(async function (key) {
const filePath = this._getFilePathByKey(key); const filePath = this._getFilePathByKey(key);
try { try {
if (this.options.subdirs) { if (this.options.subdirs) {
//check if the folder exists to fail faster //check if the folder exists to fail faster
const dir = path.dirname(filePath); const dir = path.dirname(filePath);
await promisify(fs.access)(dir, fs.constants.W_OK); await promisify(fs.access)(dir, fs.constants.W_OK);
}
await this._lock(filePath);
await jsonFileStore.delete(filePath, this.options);
} catch (err) {
//ignore deleting non existing keys
if (err.code !== 'ENOENT') {
throw err;
}
} finally {
await this._unlock(filePath);
} }
});
await this._lock(filePath);
await jsonFileStore.delete(filePath, this.options);
} catch (err) {
//ignore deleting non existing keys
if (err.code !== "ENOENT") {
throw err;
}
} finally {
await this._unlock(filePath);
}
});
/** /**
* cleanup cache on disk -> delete all files from the cache * cleanup cache on disk -> delete all files from the cache
*/ */
DiskStore.prototype.reset = wrapCallback(async function () { DiskStore.prototype.reset = wrapCallback(async function () {
const readdir = promisify(fs.readdir); const readdir = promisify(fs.readdir);
const stat = promisify(fs.stat); const stat = promisify(fs.stat);
const unlink = promisify(fs.unlink); const unlink = promisify(fs.unlink);
return await deletePath(this.options.path, 2); return await deletePath(this.options.path, 2);
async function deletePath(fileOrDir, maxDeep) { async function deletePath(fileOrDir, maxDeep) {
if (maxDeep < 0) { if (maxDeep < 0) {
return; return;
}
const stats = await stat(fileOrDir);
if (stats.isDirectory()) {
const files = await readdir(fileOrDir);
for (let i = 0; i < files.length; i++) {
await deletePath(path.join(fileOrDir, files[i]), maxDeep - 1);
}
} else if (stats.isFile() && /[/\\]diskstore-[0-9a-fA-F/\\]+(\.json|-\d\.bin)/.test(fileOrDir)) {
//delete the file if it is a diskstore file
await unlink(fileOrDir);
}
} }
const stats = await stat(fileOrDir);
if (stats.isDirectory()) {
const files = await readdir(fileOrDir);
for (let i = 0; i < files.length; i++) {
await deletePath(path.join(fileOrDir, files[i]), maxDeep - 1);
}
} else if (
stats.isFile() &&
/[/\\]diskstore-[0-9a-fA-F/\\]+(\.json|-\d\.bin)/.test(fileOrDir)
) {
//delete the file if it is a diskstore file
await unlink(fileOrDir);
}
}
}); });
/** /**
* locks a file so other forks that want to use the same file have to wait * locks a file so other forks that want to use the same file have to wait
* @param {string} filePath * @param {string} filePath
@ -220,10 +219,10 @@ DiskStore.prototype.reset = wrapCallback(async function () {
* @private * @private
*/ */
DiskStore.prototype._lock = function (filePath) { DiskStore.prototype._lock = function (filePath) {
return promisify(lockFile.lock)( return promisify(lockFile.lock)(
filePath + '.lock', filePath + ".lock",
JSON.parse(JSON.stringify(this.options.lockFile)) //the options are modified -> create a copy to prevent that JSON.parse(JSON.stringify(this.options.lockFile)) //the options are modified -> create a copy to prevent that
); );
}; };
/** /**
@ -234,7 +233,7 @@ DiskStore.prototype._lock = function (filePath) {
* @private * @private
*/ */
DiskStore.prototype._unlock = function (filePath) { DiskStore.prototype._unlock = function (filePath) {
return promisify(lockFile.unlock)(filePath + '.lock'); return promisify(lockFile.unlock)(filePath + ".lock");
}; };
/** /**
@ -244,18 +243,18 @@ DiskStore.prototype._unlock = function (filePath) {
* @private * @private
*/ */
DiskStore.prototype._getFilePathByKey = function (key) { DiskStore.prototype._getFilePathByKey = function (key) {
const hash = crypto.createHash('md5').update(key + '').digest('hex'); const hash = crypto
if (this.options.subdirs) { .createHash("md5")
//create subdirs with the first 3 chars of the hash .update(key + "")
return path.join( .digest("hex");
this.options.path, if (this.options.subdirs) {
'diskstore-' + hash.substr(0, 3), //create subdirs with the first 3 chars of the hash
hash.substr(3), return path.join(
); this.options.path,
} else { "diskstore-" + hash.substr(0, 3),
return path.join( hash.substr(3)
this.options.path, );
'diskstore-' + hash } else {
); return path.join(this.options.path, "diskstore-" + hash);
} }
}; };