mongodb-odm
mongodb-odm copied to clipboard
Create a hook to allow loading documents from cache
Hi! In my bundle I have a custom document persister class that extends Doctrine\ODM\MongoDB\Persisters\DocumentPersister. I've faced some troubles extending it because of a number of private properties and methods in parent class. Question: is there some big reason why DocumentPersister has so many private declarations that makes it's inheritance a huge pain? Is it possible to make some of it protected?
What is your use case for extending DocumentPersister?
I've implemented a MongoDB document caching using Symfony 3 build in cache system.
Following your suggestion extended a DocumentPersister.
Oh, I wasn't suggesting that DocumentPersister should be extended, I was pointing out a potential place that cache handling could land. IMO extending this class is bad idea.
Also to answer your question: making things public requires us to maintain BC and there are places in ODM we don't want end-user to use on his/her own.
Also to answer your question: making things public requires us to maintain BC and there are places in ODM we don't want end-user to use on his/her own.
I didn't mean to make it public, just protected.
Oh, I wasn't suggesting that DocumentPersister should be extended, I was pointing out a potential place that cache handling could land. IMO extending this class is bad idea.
Ok, here are my thoughts: What do you think of creating a new event listener type, say preFetch (or preFind) and call it before this line passing a document object (or some variable) as reference? If a document is loaded in this event (from cache or whatever) then don't load it from MongoDB.
I realize it's a big work and it probably won't be ever done, but I believe it can help other developers to implement an outstanding cache systems with this event listener type.
cc @alcaeus @jmikola @jwage
Something like this:
if (1 === count($criteria) && array_key_exists('_id', $criteria) &&
$this->eventManager->hasListeners(Events::preFetch)) {
$eventArgs = new EventArgs($this, $document, $criteria);
$this->eventManager->dispatchEvent(Events::preFetch, $eventArgs);
$result = $eventArgs->getData();
}
if (null === $result) {
$cursor = $this->collection->find($criteria);
if (null !== $sort) {
$cursor->sort($this->prepareSortOrProjection($sort));
}
$result = $cursor->getSingleResult();
}
postSave and postRemove events may be used for cache actualization and invalidation.
I think it might be good idea to take a look at ORM's 2nd level cache and port the concept over here.
It's a good idea but it will take a lot of time to port it into ODM and will take your team's resources to maintain it. IMO my solution is more flexible and allows external developers deal with cache by their own. Some systems (like Symfony 3) has it's own cache implementations and it will be really easy to connect it with ODM having such an event type.
The discussion of my first question came too far, maybe it will be better to create a new issue ant tag it with feature or idea?
I'll rename the issue and tag it :)
Thanks :)
+1
This issue has been automatically marked as stale because it has not had any recent activity. It will be closed in a week if no further activity occurs. Thank you for your contributions.
+1 for adding the Event hook as suggested by @alex-bacart
mongodb-odm is great but the hydration process takes too much and is loading the same documents over and over because the references are the same.
I found that using preLoad and postLoad events I can get from the cache and save to the cache using my own logic based on the document ID.
However I'm unable to figure out how push the cached item back.
Any ideas?
is loading the same documents over and over because the references are the same.
This doesn't sound right. After the document is loaded (and hydrated) it's stored in unit of work's identity map, and that very object is reused each time ODM needs it.
However I'm unable to figure out how push the cached item back.
Probably postPersist and postUpdate events?