Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doctrine 2 result cache invalidation

I'm using Doctrine 2's result cache on a query retrieving the number of new messages of a user (messaging app):

$query->useResultCache(true, 500, 'messaging.nb_new_messages.'.$userId);

I tried to invalidate this cache like this (in my entity repository):

public function clearNbNewMessagesOfUserCache($userId) {
    $cacheDriver = $this->getEntityManager()->getConfiguration()->getResultCacheImpl();
    $result  = $cacheDriver->delete('skepin_messaging.nbNewMessages.'.$userId);

    if (!$result) {
        return false;
    }

    return $cacheDriver->flushAll();
}

So that I don't need to make a useless query on each page of my website.

My questions: is that a recommended practice? Will I eventually run into problems?

like image 478
Nanocom Avatar asked Jun 23 '12 18:06

Nanocom


1 Answers

I had the idea to build an onFlush hook. There you have all entities queued for inserts, updates and deletes hence you can invalidate the caches depending on entity name and identifier etc.

Unfortunately, I have not yet build any event listeners but I definitely plan to build such a thing for my project.

Here is a link to the doctrine documentation for the onFlush event

Edit: There is even an easier way to implement events. In an entity class you can add @HasLifecycleCallbacks to the annotations and than you can define a function with a @PreUpdate or @PrePersist annotation. Than every time this model is updated or persisted this function will be called.

/**
 * @Entity
 * @Table(name="SomeEntity")
 * @HasLifecycleCallbacks
 */
class SomeEntity
{
    ...

    /**
     * @PreUpdate
     * @PrePersist
     */
    public function preUpdate()
    {
        // This function is called every time this model gets updated
        // or a new instance of this model gets persisted

        // Somethink like this maybe... 
        // I have not yet completely thought through all this.
        $cache->save(get_class($this) . '#' . $this->getId(), $this);
    }
}

So maybe this can be used to invalidate every single instance of an entity?

like image 86
Hanniball Avatar answered Oct 20 '22 00:10

Hanniball