我離一個非常簡單的帶有 nodejs 的資料庫快取系統只有一步之遙。我不想安裝像 Redis 這樣的完整資料處理解決方案,我只需要讀取和快取資料,有時從 DB 重新加載它,沒有任何處理功能,所以我實作了這個:
- 在我的快取模塊中,對于第一次評估,我查詢 DB 并在 module.exports 中回傳結果
- 因此
require,此模塊的所有后續操作都將回傳快取的值,而不是再次查詢資料庫>>到目前為止,我做到了,并將消耗的時間除以 5。 - 然后我需要一個函式來重新加載模塊>>我在那里失敗了......
我覺得我離成功只有一步之遙,這是我實作的(我運行 node.js v14.15.1,我簡化了所有代碼以使其更具可讀性......):
首先,我讓模塊自己匯出權限,它可以作業,當我需要模塊時,我得到了權限串列:
/** FILE cached_permissions.js **/
const permissionModel = require("../models/permission.model")
getPermissionsAtInit = async () => {
return await permissionModel.find().exec()
}
module.exports = getPermissionsAtInit()
然后,經典路由檔案:
/** FILE permissions.route.js **/
// Permission service
const PermissionService = require("../services/permission.service")
// Routes to get permissions from DB
app.get("/api/permissions", async (req, res) => {
res.send(await PermissionService.getPermissionsFromDB()} )
// Route to get permission from cache
app.get("/api/cached-permissions", async (req, res) => {
res.send(await PermissionService.getCachedPermissions()})
// Route to reset permission cache
app.get("/api/reset-cache", async (req, res) => {
await PermissionService.resetCache()
res.send("cache reseted")})
這是權限服務模塊
/** FILE permission.service.js */
// Module with cached permissions
const cachedPermissions = require("./cached_permissions.js")
// Module to query the db
const permissionModel = require("../models/permission.model")
class PermissionService {
static getPermissionsFromDB = async () => {
// Mongoose query to get data from DB
return await permissionModel.find().exec()
}
static getCachedPermissions = () => {
// Directly returns value from cached module
return cachedPermissions
}
static resetCache = async () => {
// firstly we delete the cached module
delete require.cache[require.resolve("./cached_permissions.js")]
// then we require again the module to force the re-cache
require("./cached_permissions.js")
}
}
module.exports = PermissionService
所以我可以運行以下命令:
- http call /api/permissions >> 從 DB 中回傳權限串列 ~50ms
- http 呼叫 /api/cached-permissions >> 回傳相同的權限串列 ~10ms
- 我手動更新 mongoDB 中的資料
- 第二次 http 呼叫 /api/permissions >> 回傳更新資料
- 第二次 http 呼叫 /api/cached-permissions >> 回傳第一組資料
所以這么好,這是預期的行為
- 然后 http 呼叫 /api/reset-cache
- 第三次呼叫 /api/cached-permissions >> 仍然回傳未更新的資料
I know the /api/reset-cache is done because I console.log Object.keys(require.cache), and I can see it deleted after the delete require.cache[...] and I can see it appear again after the new require("./cached_permissions.js").
But anyway, when I call again /api/cached-permissions, the value has not been updated. It feels like the const cachedPermissions = require("./cached_permissions.js") from my file permission.service.js has been loaded only once when the server starts when the permissions.route.js file require the permission.service.js file, and not each time a route is called, even if I reload a specific module.
Do you know a way I could reload the module in already loaded file, or update the value of a module in an alreay loaded file or some other way to make this work? I feel like I am a very little step away of a very simple DB cache system...
uj5u.com熱心網友回復:
感覺就像
const cachedPermissions = require("./cached_permissions.js")我的檔案permission.service.js 在服務器啟動時只加載了一次,而不是每次呼叫路由時
好吧,這正是您撰寫代碼的目的。cachedPermissions是您的 permission.service.js 模塊中的螞蟻,const您永遠不會更新該常量。如果相反,您會這樣做
static getCachedPermissions = () => {
// Directly returns value from cached module
return require("./cached_permissions.js");
}
它會在每個請求上加載模塊(從模塊快取中,或者評估模塊代碼,如果是新鮮的)。
但實際上沒有理由為此使用模塊快取。您的權限服務模塊中的一個簡單變數就足夠了:
/* permission.service.js */
const permissionModel = require("../models/permission.model"); // Module to query the db
async function getPermissionsFromDB() {
// Mongoose query to get data from DB
return await permissionModel.find().exec()
}
let cachedPermissions = getPermissionsFromDB();
module.exports.getPermissionsFromDB = getPermissionsFromDB;
module.exports.getCachedPermissions = () => cachedPermissions;
module.exports.resetCache = () => {
cachedPermissions = getPermissionsFromDB();
};
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/442618.html
