Best practice per l'implementazione della cache personalizzata?


17

Per ogni istanza di ogni tipo di entità, generi un numero di cache, chiamato come: [module_name]__[entity_type]__[entity_id]__[string_depending_on_where_the_cache_came_from]

Ora, ogni volta che un'entità viene aggiornata, desidero eliminare tutte le cache a partire dal tipo di entità e dall'ID pertinenti.

Come devo conservare / cancellare queste cache?

Attualmente ho solo cache_set () , ma questo presenta un problema quando desidero cancellare, poiché non conosco i nomi di tutte le cache pertinenti. È sicuro eliminare le voci della cache con un db_delete ()?


Se non conosci i nomi di tutte le cache pertinenti, come puoi utilizzare db_delete()?
kiamlaluno

Risposte:


6

Per eliminare voci da una cache, è necessario utilizzare cache_clear_all () . Il motivo è che l'implementazione della cache utilizzata non ha potuto utilizzare una tabella del database nel database attivo. Questo è ciò che accade con la classe DrupalDatabaseCache , ma non dovrebbe essere vero per ogni classe.

Se guardi _cache_get_object () (la funzione chiamata da cache_get () e cache_set () ), noterai che contiene il seguente codice.

  static $cache_objects; 
  if (!isset($cache_objects[$bin])) {
    $class = variable_get('cache_class_' . $bin);
    if (!isset($class)) {
      $class = variable_get('cache_default_class', 'DrupalDatabaseCache');
    }
    $cache_objects[$bin] = new $class($bin);
  }
  return $cache_objects[$bin];

La classe per l'implementazione della cache potrebbe essere diversa per ciascun archivio del cestino della cache e anche quella predefinita potrebbe essere cambiata.

Il sistema di cache dello stato di aggiornamento privato spiega esattamente perché le normali funzioni della cache non sono utilizzate in _update_cache_clear () , _update_cache_get () e _update_cache_set () . (L'enfasi è mia.)

In particolare NON utilizziamo l'API della cache principale per salvare i dati recuperati sugli aggiornamenti disponibili. È di vitale importanza che questa cache venga cancellata solo quando la popoliamo dopo aver recuperato correttamente i nuovi dati di aggiornamento disponibili. L'utilizzo dell'API della cache principale comporta ogni sorta di potenziali problemi che provocherebbero sempre il tentativo di recuperare i dati di aggiornamento disponibili, anche se un sito ha una "durata minima della cache" (che è sia un minimo che un massimo), o se un sito utilizza memcache o un altro sistema cache collegabile che assume cache volatili.

Il modulo Update Manager utilizza ancora la tabella {cache_update}, ma invece di utilizzare cache_set(), cache_get()e cache_clear_all(), ci sono funzioni di supporto private che implementano queste stesse attività di base ma assicurano che la cache non venga cancellata prematuramente e che i dati siano sempre archiviati nella database, anche se è in uso memcache o un altro backend della cache.

Update Manager ha esigenze specifiche che sono necessarie perché il tentativo di recuperare le informazioni di aggiornamento troppo frequentemente potrebbe causare problemi con i server Drupal.org, considerando che l'Update Manager può potenzialmente recuperare le informazioni di aggiornamento da qualsiasi sito che esegue Drupal.

Nel tuo caso, potresti usare [module_name]__[entity_type]__[entity_id]__[string_depending_on_where_the_cache_came_from]come ID cache per un singolo archivio bin cache. Nel caso in cui sia necessario eliminare tutte le voci per un'entità, è possibile utilizzare il seguente codice.

cache_clear_all("{$module}__{$entity_type}__{$entity_id}__", $bin, TRUE);

Se non è possibile ottenere il valore da assegnare $modulequando si cancella la cache o si desidera eliminare la voce della cache indipendentemente dal modulo per il quale sono stati memorizzati i dati nella cache, è possibile utilizzare un ID cache diverso, come [entity_type]__[entity_id]__[string_depending_on_where_the_cache_came_from], o [entity_type]__[entity_id]__[module_name]__[string_depending_on_where_the_cache_came_from]. cache_clear_all()elimina tutte le voci della cache con un ID cache che inizia con la stringa passata come argomento, quando lo $wildcardè TRUE, e l'ID cache no '*'. In questo caso, la cache verrebbe cancellata con il seguente codice.

cache_clear_all("{$entity_type}__{$entity_id}__", $bin, TRUE);

8

Non riesco a pensare a una buona ragione per cui la caduta manuale delle voci causerebbe un problema. Ciò presuppone, ovviamente, che stai usando MySQL come backend per la tua cache particolare; anche se penso che lo stesso valga per qualsiasi altro tipo di backend della cache, il metodo per cancellare non sarebbe necessariamente una query del database.

Se prendi ad esempio il modulo di aggiornamento principale, ignora le cache_*funzioni e cancella la sua cache manualmente:

function _update_cache_clear($cid = NULL, $wildcard = FALSE) {
  if (empty($cid)) {
    db_delete('cache_update')
      // Clear everything except fetch task information because these are used
      // to ensure that the fetch task queue items are not added multiple times.
      ->condition('cid', 'fetch_task::%', 'NOT LIKE')
      ->execute();
  }
  else {
    $query = db_delete('cache_update');
    if ($wildcard) {
      $query->condition('cid', $cid . '%', 'LIKE');
    }
    else {
      $query->condition('cid', $cid);
    }
    $query->execute();
  }
}

Penso sempre "se è abbastanza buono per il core, è abbastanza buono per me" :)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.