Boost Cache operations on entity CRUD

Created on 25 June 2022, almost 3 years ago
Updated 28 May 2023, almost 2 years ago

Problem/Motivation

When entities are created or changed the cached data should follow.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

📌 Task
Status

Active

Version

1.0

Component

Code

Created by

🇩🇪Germany c-logemann Frankfurt/M, Germany

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇩🇪Germany c-logemann Frankfurt/M, Germany

    Just thinking about the fact that we are only caching pages by path. So when we operate on entity crud we need to figure out which entity path and which aliases are involved. And maybe we should also operate on alias operations itself (maybe in an own issue).

  • 🇩🇪Germany c-logemann Frankfurt/M, Germany

    Regarding event subscription

    I changed my mind to use event subscriptions when they are faster than hooks. This means that there should be I "direct" event in this case the core entity module or something deeper in core or symfony itself.
    It seems that there is currently only the EntityTypeEvent named above in core which works with type events and not the entity changes itself. For this there is a contrib Module entity_events which using hooks and providing events for this. This doen't make things faster. For now it's better to use entity hooks and when core is extended in this direction we can upgrade this. But when you take a look to the following long lasting issue, this will not come before Drupal 11: 📌 Add events for matching entity hooks Needs work

  • 🇧🇪Belgium davidiio

    Hi,

    We need this to work on some of our websites and we thought that simply start by deleting boost cache file when a node is updated or deleted is enough.
    We don't know how to know every page using that node but we though that we might include a configuration field with a list of views path we want to always update when nodes are updated or deleted.

    Here is a patch if anyone is interested. It adds a cache.entity service that exposed a delete methode that take a node in parameter. It gets all paths for that node (languages) and try to delete associated boost cache file on hook_entity_type_update and hook_entity_type_delete

    Sorry for not working on the issue fork but I wasn't sure how to do this and wanted to try fast on our installed boost module.

  • 🇩🇪Germany c-logemann Frankfurt/M, Germany

    @davidiio
    It is really easier to review code by just reading with the issue branches. But it's possible to check without installing. I think the core pint of the solution is this function:

    /**
       * {@inheritdoc}
       */
      public function delete(\Drupal\Core\Entity\EntityInterface $entity) {
        foreach ($this->languageManager->getLanguages() as $langcode => $language) {
          $path = $this->pathAliasManager->getAliasByPath('/node/' . $entity->id(), $langcode);
          $uri = $this->boostCacheFile->getUri( '/' . $langcode . $path);
          if (!file_exists($uri)) {
            \Drupal::logger('boost')->error('Delete route @uri can not be done.',
              [
                '@uri' => $uri,
              ]
            );
            continue;
          }
          $this->boostCacheFile->delete($uri);
        }
      }
    

    You start at entity hooks that works for all entity types but end up in a hard code node path alias solution?
    This will lead to unwanted cache file deletions like this: Somebody is changing term/5 and your code will delete the boost cache alias for node/5.

    I will not say that the code to retrieve entity paths is already perfect but it is open for alle aliased paths incl. terms for example.

  • 🇧🇪Belgium davidiio

    Thank you for your feedback!
    Yes I wanted to use a general approach but ending up making it quickly work for nodes.

    Here is an updated patch that I tried, it worked on nodes, terms and users and don't seem to have any side effects on other entity types.
    It affects only entities that have a toUrl() method so only the ones that are actually cached by boost since it cache them using their paths as far as I understand. I did see some entities passing hasLinkTemplate and returning a URL but in the end file does not exists and so this code has no effect. For example when editing a menu item in admin interface, the entity menu_link_content does return a URL like /admin/structure/menu/item/19/edit" for example but no boost cache file will be found.

      public function delete(\Drupal\Core\Entity\EntityInterface $entity) {
        if(!$entity->hasLinkTemplate('canonical')) {
          // If the entity does not have a canonical link, it has no route, no path, no boost cache file
          // and we don't need to delete anything.
          // Plus $entity->toUrl() will throw an exception.
          return;
        }
    
        foreach ($this->languageManager->getLanguages() as $langcode => $language) {
          if(!$entity->hasTranslation($langcode)) {
            continue;
          }
    
          $entity = $entity->getTranslation($langcode);
          $path = $entity->toUrl()->toString();
          $uri = $this->boostCacheFile->getUri($path);
    
          if (!file_exists($uri)) {
            \Drupal::logger('boost')->error('Delete route @uri can not be done.',
              [
                '@uri' => $uri,
              ]
            );
            continue;
          }
          $this->boostCacheFile->delete($uri);
        }
      }
    }
    

    We will keep testing and iterating.
    Thank for your help!

Production build 0.71.5 2024