Some of our meteor methods need a lot of DB access to check permissions on each of the objects that are returned. We came across this article that explains how to create a memoizer for Meteor:
What I’m thinking could be really nice (and might even be a public meteor package), is to create a new local memoizer for each meteor method call, that stores each DB result, so that you can access it as many times as you want, over the course of execution of a method.
And when a method ends, the cache is emptied.
It’s a kind of in-memory MiniMongo for the duration of a method:
Meteor.methods({
fetchTodos() {
this.cacher = new Cache();
const todos = Todos.find({ userId: this.userId }).fetch();
const allowedTodos = todos.filter(({ listId, ...todo }) => {
const permissions = TodoLists.findOne({ _id: listId }); // Each identical todo list will be fetched once
const user = Users.findOne({ _id: this.userId }); // Will only be fetched once
return isAllowedToSeeTodos(permissions, user, todo);
});
this.cacher.destroy();
return allowedTodos;
},
});
This is just an example, and it’s sloppy, but you could write this, and it would only really fetch your user once, as well as any todolist once if it is fetched multiple times. Because sometimes, fetching all of your data at the beginning once and passing it down can result in a horrible code.
There are a few things to think about:
- Invalidating cache if you update something in the middle of a method and then try to refetch it. (the old version of the document will come back from the cache)
- Can the cache be invisible to the rest of your code? i.e. can you just write Users.find().fetch() and it will know to look for any existing cache before going to the DB? To make this work elegantly it’d be a must have
Has anyone implemented something like this?