Refresh output caches per block type

Permalink
I have three blocks that depend on each other and are all cached:
author, authorbox, lead

The author block is a block that contains all the author's information (name, picture, etc.) and is in a central location (only exists once per author). The other two blocks exist on every article page (more than 3000 pages currently). They display information from the author block.

When I change the author block, e.g. the name of the author, I need to clear the cache of the other two blocks on ALL pages.

I have written a method to do that, and it works. However it has gotten incredibly slow now - it takes at least 20 seconds to execute (shown in the php slowlog frequently):

/**
     * Refresh output caches of all blocks with given blocktype handle(s) on every page
     * @param string|string[] $blockTypeHandles Block type handles
     * @param string $areaHandle Area handle
     */
    public static function refreshOutputCachesEverywhere($blockTypeHandles, $areaHandle = 'Main') {
        $blockTypeHandles = is_array($blockTypeHandles) ? $blockTypeHandles : array($blockTypeHandles);
        $homePage = Page::getByID(Page::getHomePageID());
        $pageList = new PageList();
        $pageList->filterByPath($homePage->getCollectionPath(), true);
        $pages = $pageList->getResults();
        /** @var Page[] $pages */
        foreach ($pages as $page) {
            $blocks = $page->getBlocks($areaHandle);
            foreach ($blocks as $block) {


So I iterate through ALL pages and ALL blocks, and refresh the block output cache of the desired block types (authorbox and lead).

Is there a faster way to do this? Or do you have any other suggestions?

Something like BlockType::getByHandle('authorbox')->refreshBlockOutputCache(); would be great. This doesn't seem to exist.

entreprenr
 
JohntheFish replied on at Permalink Reply
JohntheFish
That seems like a lot of work for something that could be attacked with the simpler approach of just flushing the entire cache.

I suppose it depends on how busy the site is and how often the blocks are edited.

If you do need to flush blocks individually, you could put your logic in an on_start event handler that would do it one page at a time when the page is rendered. Look ahead at blocks on the page and if any blocks of the author type have newer dates than blocks of the other types, flush the cache for the other block types.

If the blocks are all in one area, you could also put the logic it in an override/extension of the Area class. Though that could lag if the page cache is active.