mongodb-odm icon indicating copy to clipboard operation
mongodb-odm copied to clipboard

Create a hook to allow loading documents from cache

Open alex-bacart opened this issue 9 years ago • 14 comments

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?

alex-bacart avatar Aug 23 '16 13:08 alex-bacart

What is your use case for extending DocumentPersister?

malarzm avatar Aug 23 '16 13:08 malarzm

I've implemented a MongoDB document caching using Symfony 3 build in cache system. Following your suggestion extended a DocumentPersister.

alex-bacart avatar Aug 23 '16 13:08 alex-bacart

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.

malarzm avatar Aug 23 '16 14:08 malarzm

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.

alex-bacart avatar Aug 23 '16 14:08 alex-bacart

cc @alcaeus @jmikola @jwage

malarzm avatar Aug 23 '16 14:08 malarzm

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.

alex-bacart avatar Aug 23 '16 19:08 alex-bacart

I think it might be good idea to take a look at ORM's 2nd level cache and port the concept over here.

malarzm avatar Aug 23 '16 21:08 malarzm

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?

alex-bacart avatar Aug 24 '16 08:08 alex-bacart

I'll rename the issue and tag it :)

malarzm avatar Aug 24 '16 08:08 malarzm

Thanks :)

alex-bacart avatar Aug 24 '16 08:08 alex-bacart

+1

manuelbcd avatar Oct 19 '16 15:10 manuelbcd

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.

stale[bot] avatar Jan 21 '19 06:01 stale[bot]

+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?

hjardines avatar May 08 '22 00:05 hjardines

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?

malarzm avatar May 08 '22 11:05 malarzm