-
Hey guys, I need help with this issue using caching. My system has public caches and I also need to implement a private cache for user resources. And I'll explain better: Currently I have caches like this:
I would need something like this:
The clientId I have in my session: I need to find a way to build the cache key dynamically using my session's clientId in an action. Thanks in advance. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
To cover it, in my project I created a custom Cacher middleware. In my case I add a // project-cacher.middleware.js
const _ = require("lodash");
const { isFunction, isObject } = require("moleculer").Utils;
const Cachers = require("moleculer").Cachers;
module.exports = function ProjectCacherMiddleware(opts = {}) {
let cacher;
return {
name: "ProjectCacher",
created(broker) {
if (broker.cacher) {
throw new Error(
"Built-in cacher is enabled! Project Cacher can't work besides built-in cacher!"
);
}
cacher = Cachers.resolve(opts);
cacher.init(broker);
broker.cacher = cacher;
},
localAction(next, action) {
if (!cacher) return next;
const opts = _.defaultsDeep(
{},
isObject(action.cache) ? action.cache : { enabled: !!action.cache }
);
opts.lock = _.defaultsDeep(
{},
isObject(opts.lock) ? opts.lock : { enabled: !!opts.lock }
);
if (opts.enabled !== false) {
const isEnabledFunction = isFunction(opts.enabled);
return function cacherMiddleware(ctx) {
if (isEnabledFunction) {
if (!opts.enabled.call(ctx.service, ctx)) {
// Cache is disabled. Call the handler only.
return next(ctx);
}
}
// Disable caching with `ctx.meta.$cache = false`
if (ctx.meta["$cache"] === false) return next(ctx);
// Cache is enabled but not in healthy state
// More info: https://github.com/moleculerjs/moleculer/issues/978
if (this.connected === false) {
this.logger.debug(
"Cacher is enabled but it is not connected at the moment... Calling the handler"
);
return next(ctx);
}
const project = ctx.meta.project || "null";
const cacheKey =
project +
":" +
this.getCacheKey(action.name, ctx.params, ctx.meta, opts.keys, opts.keygen);
/*
// Using lock
if (opts.lock.enabled !== false) {
let cachePromise;
if (opts.lock.staleTime && this.getWithTTL) {
// If enable cache refresh
cachePromise = this.getWithTTL(cacheKey).then(({ data, ttl }) => {
if (data != null) {
if (opts.lock.staleTime && ttl && ttl < opts.lock.staleTime) {
// Cache is stale, try to refresh it.
this.tryLock(cacheKey, opts.lock.ttl)
.then(unlock => {
return next(ctx)
.then(result => {
// Save the result to the cache and realse the lock.
return this.set(
cacheKey,
result,
opts.ttl
).then(() => unlock());
})
.catch(() => {
return this.del(cacheKey).then(() =>
unlock()
);
});
})
.catch(() => {
// The cache is refreshing on somewhere else.
});
}
}
return data;
});
} else {
cachePromise = this.get(cacheKey);
}
return cachePromise.then(data => {
if (data != null) {
// Found in the cache! Don't call handler, return with the content
ctx.cachedResult = true;
return data;
}
// Not found in the cache! Acquire a lock
return this.lock(cacheKey, opts.lock.ttl).then(unlock => {
return this.get(cacheKey).then(content => {
if (content != null) {
// Cache found. Realse the lock and return the value.
ctx.cachedResult = true;
return unlock().then(() => {
return content;
});
}
// Call the handler
return next(ctx)
.then(result => {
// Save the result to the cache and realse the lock.
this.set(cacheKey, result, opts.ttl).then(() =>
unlock()
);
return result;
})
.catch(e => {
return unlock().then(() => {
return Promise.reject(e);
});
});
});
});
});
}
*/
// Not using lock
return this.get(cacheKey).then(content => {
if (content != null) {
// Found in the cache! Don't call handler, return with the content
ctx.cachedResult = true;
return content;
}
// Call the handler
return next(ctx).then(result => {
// Save the result to the cache
this.set(cacheKey, result, opts.ttl);
return result;
});
});
}.bind(cacher);
}
return next;
}
};
}; and here is the using in module.exports = {
cacher: null, // We use custom cacher middleware
// ...
// Register custom middlewares
middlewares: [
require("./middlewares/project-cacher.middleware")({
type: "MemoryLRU",
options: { max: 100, ttl: 60 }
})
], |
Beta Was this translation helpful? Give feedback.
To cover it, in my project I created a custom Cacher middleware. In my case I add a
project
ID to the cache keys as prefix. Here is the code of my middleware: