Return early in CacheTagsChecksumTrait::isValid() (and possibly elsewhere) if there are no tags to check

Created on 21 February 2024, 11 months ago
Updated 11 March 2024, 11 months ago

Problem/Motivation

Found in 📌 Track cache tag queries separately in performance tests Active .

Cache tag operations don't do anything if an empty array is passed, which is fine, but because we now track them separately from database queries, we see a lot of operations that are non-ops. If we instead return early or avoid calling the methods with an empty tags list, we'll only see the ones that actually result in lookups.

This will in turn make it easier to see if we're doing unexpected cache tag look-ups anywhere.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

📌 Task
Status

Fixed

Version

11.0 🔥

Component
Cache 

Last updated 3 days ago

Created by

🇬🇧United Kingdom catch

Live updates comments and jobs are added and updated live.
  • Performance

    It affects performance. It is often combined with the Needs profiling tag.

Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @catch
  • First commit to issue fork.
  • 🇧🇪Belgium gorkagr

    Hi!
    I hope is fine, i have added the snippet of @wim Leers in https://www.drupal.org/project/drupal/issues/3421881#comment-15456992 📌 Track cache tag queries separately in performance tests Active in here :)

  • Pipeline finished with Success
    11 months ago
    Total: 485s
    #101199
  • Status changed to Needs review 11 months ago
  • Status changed to Needs work 11 months ago
  • 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺

    The code looks fine (😇), but the comment doesn't quite make sense to me: the comment is more complicated than the logic here 😄 It's much simpler: if there's no cache tags, then there is no cache tag to invalidate, hence it's always valid.

  • 🇬🇧United Kingdom catch

    I think the change here is good, but also just realised we could do the same early return in the decorator in 📌 Track cache tag queries separately in performance tests Active too.

  • 🇧🇪Belgium gorkagr

    Agreed on the comment, it is always the hardest part :D :D , but i liked your last sentence so i have used it ;)

    @cat, you mean in core/modules/system/tests/modules/performance_test/src/Cache/CacheTagsChecksumDecorator.php::isValid(), correct?

    if we do as well there the

        if (empty($tags)) {
          return TRUE;
        }
    

    should we also do a $this->logCacheTagOperation([], 0, 0, CacheTagOperation::isValid); (or smth like that before the return? Or there is no need to log the operation?

  • Pipeline finished with Success
    11 months ago
    Total: 499s
    #101353
  • 🇬🇧United Kingdom catch

    Thinking about it - we should call the child class so it's a proper decorator, but skip logging because we know there's nothing to log. Probably needs a separate comment. The empty cache tag operations create a lot of noise in grafana tempo, not having them there will make it easier to find things we need to change.

    📌 Track cache tag queries separately in performance tests Active just landed which means we can do that change here now, it'll mean also adjusting the assertions we just added.

  • Status changed to Needs review 11 months ago
  • 🇬🇧United Kingdom catch

    Went ahead and implemented #9. I also noticed that we were still sending some cache tag queries to grafana, so moved that logic to a helper so it's the same in both places we check.

  • Pipeline finished with Failed
    11 months ago
    #101520
  • Pipeline finished with Success
    11 months ago
    Total: 493s
    #101544
  • Status changed to RTBC 11 months ago
  • 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺

    Just a nit — this looks great!

    Also, am I missing something, or is this actually saving DB queries?! Nonsensical queries like

    SELECT [tag], [invalidations] FROM {cachetags} WHERE [tag] IN ()'
    

    🙈

  • 🇬🇧United Kingdom catch

    It doesn't save any real database queries, we already check that there is something new to query in CacheTagChecksumTrait::calculateChecksum and similar places, so it's mostly removing noise when profiling (either traces in grafana tempo or less function calls to look at in xhprof and similar too) and a small micro-optimization.

  • Pipeline finished with Success
    11 months ago
    Total: 474s
    #101705
  • 🇧🇪Belgium kristiaanvandeneynde Antwerp, Belgium

    I noticed we're only changing isValid(), what about the other two methods we're tracking in our perfrmance tests?

    Re #11, not really:

        $query_tags = array_diff($tags, array_keys($this->tagCache));
        if ($query_tags) {
          $tag_invalidations = $this->getTagInvalidationCounts($query_tags);
          $this->tagCache += $tag_invalidations;
          // Fill static cache with empty objects for tags not found in the storage.
          $this->tagCache += array_fill_keys(array_diff($query_tags, array_keys($tag_invalidations)), 0);
        }
    

    If $tags is empty, then so will $query_tags so we weren't running a query for that. It was showing up in OpenTelemtry, though, because we were tracking all calls in the decorator. This patch fixes that so you'll see a significantly reduced amount of them being tracked.

  • Status changed to Fixed 11 months ago
  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    Committed and pushed 02c07301fc to 11.x and 86594c44d6 to 10.3.x. Thanks!

    • alexpott committed 86594c44 on 10.3.x
      Issue #3422981 by catch, gorkagr, Wim Leers: Return early in...
    • alexpott committed 02c07301 on 11.x
      Issue #3422981 by catch, gorkagr, Wim Leers: Return early in...
  • 🇧🇪Belgium kristiaanvandeneynde Antwerp, Belgium

    Sooooo... a follow-up for getCurrentChecksum and invalidateTags then? :D

  • 🇧🇪Belgium kristiaanvandeneynde Antwerp, Belgium

    More specifically, I was thinking about:

    • Only the top of CacheTagsChecksumDecorator::invalidateTags() because CacheTagsChecksumTrait already short-circuits if the list of tags is empty.
    • The top of CacheTagsChecksumDecorator::getCurrentChecksum()
    • The top of CacheTagsChecksumTrait::getCurrentChecksum() because it runs a bunch of code that will end up doing nothing if the list of tags is empty
  • 🇬🇧United Kingdom catch

    Good point, not sure if those are also polluting the grafana traces but even if they're not it makes some things easier to follow, opened 📌 Return early from more cache tag operations Active .

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024