php - Deleting symfony2 doctrine memcache on create/update/delete -


i'm using doctrine2 memcache (not memcached) in symfony 2.7 application. here configuration:

doctrine:     orm:         metadata_cache_driver: memcache         result_cache_driver: memcache         query_cache_driver: memcache 

i'm trying delete respective cache items on entity create/update/delete. memcache doesn't support deletion using prefix, not find easy solution delete cache items of entity on cud operations. let's have property entity, want delete caches related property on property create/update/delete. (i believe deleteall() not idea in case)

deleting using namespace workaround, think namespace can set on cache driver, not on particular entity or repository. how possible distinguish namespaces each entity?

so, i'm invalidating result cache using onflush event (this way found , article old in 2012. there better recent solution?). 1 drawback of solution define each cache id each query , define of them in service class cacheinvalidator such

namespace mybundle\listener\event; // ...  class cacheinvalidator {     //...      protected function getcacheids()     {         return array(             'mybundle\entity\blogpost' => array(                 array(                     'id' => 'posts_for_user_%d',                     'vars' => array(                         array(                             'value' => 'getuser',                             'type' => 'method',                         ),                     ),                     'change' => 'any',                 ),             ),             // add more entities etc here         );     } } 

the article author gave simple example using cache id posts_for_user_%d. fine using such simple query. problem have many queries using lot of dynamic query parameters. example, have following method in property repository can called various options:

public function findrecommendations($options = null) {     if (isset($options['limit'])) {         $limit = $options['limit'];     } elseif (is_numeric($options)) {         $limit = $options;     } else {         $limit = null;     }      $qb = $this->createquerybuilder('p');      $qb->where('p.recommend_flag = :recommend_flag');     $qb->setparameter('recommend_flag', 1);     $qb->andwhere('date(p.expired_at) > :now');     $qb->setparameter('now', date('y-m-d'));      $resultcacheparams = array(         'type'  => array('%d', '%s'),         'value' => array(1, date('ymd'))     );      if ($limit) {         $qb->setmaxresults($limit);         $resultcacheparams['type'][] = 'limit%d';         $resultcacheparams['value'][] = $limit;     }      $resultcacheid = vsprintf(         'property_findrecommendations_'.implode('_', $resultcacheparams['type']),         $resultcacheparams['value']     );      $query = $qb->getquery();      $query->usequerycache(true);     $query->setquerycachelifetime(21600);     $query->useresultcache(true, 21600, $resultcacheid);      return $query->getresult(); } 

so, have define 2 combinations of cache id in service class - property_findrecommendations_%d_%s , property_findrecommendations_%d_%s_limit%d, 1 using limit , other without limit.

protected function getcacheids() {     return array(         'mybundle\entity\property' => array(                 'id' => 'property_findrecommendations_%d_%s',                 'vars' => array(                     array('value' => 1), // recommend_flag                     array('value' => date('ymd')),                 ),                 'change' => 'any'             ),             array(                 'id' => 'property_findrecommendations_%d_%s_limit%d',                 'vars' => array(                     array('value' => 1), // recommend_flag                     array('value' => date('ymd')),                     array('value' => $this->container->getparameter('max_recommend_properties'))                 ),                 'change' => 'any'             ),     ); } 

this 1 parameter example. there more 1 parameters method. more parameters, more combinations of cache id definitions in service class. expensive think.

the worst case queries pagination accept dynamic page parameter. each query result each page should cached using different cache id, example property_getallproperties_%d

property_getallproperties_1 // page 1 property_getallproperties_2 // page 2 property_getallproperties_3 // page 3 .... 

i can't know current page number in method getcacheids() of service class. should calculate number of pages of properties , define array of cache ids every page number dynamically in method getcacheids()?

i feel weird , seems workaround. in addition, have search queries depends on various parameters. think difficult define in getcacheids() statically.

is there better , more graceful way invalidate doctrine memcache result cache?

update

one possible solution think of create new database table cache_key , save every cache id in table. have function generate cache id according query parameters. returns cache id in format of custom_prefix + sha1(serialize($arrayofparameters)), e.g., property_findrecommendations_xxxxxx, property_getallproperties_xxxxxx.

whenever call 2 methods findrecommendations() , getallproperties(), cache ids inserted (using replace) table cache_key below:

----------------------------------------------------- | entity      | cache_id                            | ----------------------------------------------------- | property    | property_findrecommendations_xxxxxx | | property    | property_getallproperties_xxxxxx    | ----------------------------------------------------- 

then, able retrieve them in cachevalidator service class using entity name property. 1 downside of insert/replace query has executed on every query run , additonal select executed on every onflush event.

nonetheless, can't decide whether worth or not caches invalidated on every 6 hour according lifetime setting.


Comments

Popular posts from this blog

javascript - Chart.js (Radar Chart) different scaleLineColor for each scaleLine -

apache - Error with PHP mail(): Multiple or malformed newlines found in additional_header -

java - Android – MapFragment overlay button shadow, just like MyLocation button -