Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Magento_CacheInvalidate mis-handles very large tag patterns when doing a PURGE #26255

Closed
moloughlin opened this issue Jan 3, 2020 · 6 comments · Fixed by #26256
Closed

Magento_CacheInvalidate mis-handles very large tag patterns when doing a PURGE #26255

moloughlin opened this issue Jan 3, 2020 · 6 comments · Fixed by #26256
Assignees
Labels
Component: CacheInvalidate Fixed in 2.4.x The issue has been fixed in 2.4-develop branch Issue: Confirmed Gate 3 Passed. Manual verification of the issue completed. Issue is confirmed Issue: Format is valid Gate 1 Passed. Automatic verification of issue format passed Issue: Ready for Work Gate 4. Acknowledged. Issue is added to backlog and ready for development Priority: P2 A defect with this priority could have functionality issues which are not to expectations. Reproduced on 2.4.x The issue has been reproduced on latest 2.4-develop branch Severity: S1 Affects critical data or functionality and forces users to employ a workaround. Triage: Done Has been reviewed and prioritized during Triage with Product Managers

Comments

@moloughlin
Copy link

moloughlin commented Jan 3, 2020

Preconditions:
\Magento\CacheInvalidate\Model\PurgeCache::sendPurgeRequest is responsible for taking arbitrarily large tag patterns and chunking it into HTTP PURGE requests based on the maximum header length Varnish will accept.

Currently, \Magento\CacheInvalidate\Observer\InvalidateVarnishObserver::execute will join tags with '|' and call sendPurgeRequest. Those tags themselves may include '|' characters.

\Magento\CacheInvalidate\Model\PurgeCache::splitTags will then separate on '|' and re-join components until the length of those components reaches the max. header length. This is too naive, since it may now split an individual tag (one which itself included '|' characters) across two requests. Both of those requests now have an invalid pattern - this would mean that at the very least, some purges will be missed. In the worst-case scenario, I expect this could also lead to Varnish being completely purged, depending on the tag that was incorrectly split.

For the sake of brevity, the example below has been limited to a small subset of my real-world example; as such let's pretend the max header size is 256 bytes. Note that this is a typical pattern that would result from a product save event.

((^|,)cat_p_1468(,|$))|((^|,)cat_p_1361(,|$))|((^|,)cat_p_1473(,|$))|((^|,)cat_p_930(,|$))|((^|,)cat_p_933(,|$))|((^|,)cat_p_934(,|$))|((^|,)cat_p_664(,|$))|((^|,)cat_p_487(,|$))|((^|,)cat_p_490(,|$))|((^|,)cat_p_491(,|$))|((^|,)cat_p_153(,|$))|((^|,)cat_p_156(,|$))|((^|,)cat_p_157(,|$))|((^|,)cat_p_497(,|$))|((^|,)cat_p_498(,|$))|((^|,)cat_p_499(,|$))|((^|,)cat_p_227(,|$))|((^|,)cat_p_228(,|$))|((^|,)cat_p_229(,|$))|((^|,)cat_p_242(,|$))|((^|,)cat_p_244(,|$))|((^|,)cat_p_245(,|$))

Based on my desired max. header size, this will be chunked into two separate requests:

((^|,)cat_p_1468(,|$))|((^|,)cat_p_1361(,|$))|((^|,)cat_p_1473(,|$))|((^|,)cat_p_930(,|$))|((^|,)cat_p_933(,|$))|((^|,)cat_p_934(,|$))|((^|,)cat_p_664(,|$))|((^|,)cat_p_487(,|$))|((^|,)cat_p_490(,|$))|((^|,)cat_p_491(,|$))|((^|,)cat_p_153(,|$))|((^

,)cat_p_156(,|$))|((^|,)cat_p_157(,|$))|((^|,)cat_p_497(,|$))|((^|,)cat_p_498(,|$))|((^|,)cat_p_499(,|$))|((^|,)cat_p_227(,|$))|((^|,)cat_p_228(,|$))|((^|,)cat_p_229(,|$))|((^|,)cat_p_242(,|$))|((^|,)cat_p_244(,|$))|((^|,)cat_p_245(,|$))|((^|,)cat_p_245(,|$))

Expected split behaviour:
((^|,)cat_p_1468(,|$))|((^|,)cat_p_1361(,|$))|((^|,)cat_p_1473(,|$))|((^|,)cat_p_930(,|$))|((^|,)cat_p_933(,|$))|((^|,)cat_p_934(,|$))|((^|,)cat_p_664(,|$))|((^|,)cat_p_487(,|$))|((^|,)cat_p_490(,|$))|((^|,)cat_p_491(,|$))|((^|,)cat_p_153(,|$))

((^|,)cat_p_156(,|$))|((^|,)cat_p_157(,|$))|((^|,)cat_p_497(,|$))|((^|,)cat_p_498(,|$))|((^|,)cat_p_499(,|$))|((^|,)cat_p_227(,|$))|((^|,)cat_p_228(,|$))|((^|,)cat_p_229(,|$))|((^|,)cat_p_242(,|$))|((^|,)cat_p_244(,|$))|((^|,)cat_p_245(,|$))


Steps to reproduce:

  • Have full_page cache enabled
  • Have caching application configured to Varnish
  • Run code below
<?php

require __DIR__ . '/app/bootstrap.php';
$bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $_SERVER);

class DummyEntity implements \Magento\Framework\DataObject\IdentityInterface
{
    public function getIdentities()
    {
        $ids = range(807, 1193);
        return array_map(function ($id) {
            return 'cat_p_' . $id;
        }, $ids);
    }
}

$objectManager = $bootstrap->getObjectManager();
$appState = $objectManager->get('Magento\Framework\App\State');
$appState->setAreaCode('frontend');
$eventManager = $objectManager->get('\Magento\Framework\Event\Manager');

$myObject = new DummyEntity();

$eventManager->dispatch('clean_cache_by_tags', ['object' => $myObject]);

Actual Result:
Observe two resulting PURGE requests sent to Varnish with invalid patterns (e.g. xdebug_break inside \Magento\CacheInvalidate\Model\PurgeCache::sendPurgeRequestToServers and observe the X-Magento-Tags-Pattern header)

Expected Result:

@m2-assistant
Copy link

m2-assistant bot commented Jan 3, 2020

Hi @moloughlin. Thank you for your report.
To help us process this issue please make sure that you provided the following information:

  • Summary of the issue
  • Information on your environment
  • Steps to reproduce
  • Expected and actual results

Please make sure that the issue is reproducible on the vanilla Magento instance following Steps to reproduce. To deploy vanilla Magento instance on our environment, please, add a comment to the issue:

@magento give me 2.4-develop instance - upcoming 2.4.x release

For more details, please, review the Magento Contributor Assistant documentation.

@moloughlin do you confirm that you were able to reproduce the issue on vanilla Magento instance following steps to reproduce?

  • yes
  • no

@magento-engcom-team magento-engcom-team added the Issue: Format is not valid Gate 1 Failed. Automatic verification of issue format is failed label Jan 3, 2020
moloughlin pushed a commit that referenced this issue Jan 3, 2020
…purge batching, regardless of

the size and content of provided tag pattern.
@ghost ghost assigned moloughlin Jan 3, 2020
@moloughlin
Copy link
Author

Proposed solution: #26256

@ihor-sviziev
Copy link
Contributor

This issue is duplicate of #8815, but as it have quite a good description I think it's good to keep it open.

ihor-sviziev added a commit to moloughlin/magento2 that referenced this issue Apr 24, 2020
ihor-sviziev added a commit to moloughlin/magento2 that referenced this issue Apr 24, 2020
@ghost ghost added Severity: S2 Major restrictions or short-term circumventions are required until a fix is available. Severity: S1 Affects critical data or functionality and forces users to employ a workaround. and removed Severity: S2 Major restrictions or short-term circumventions are required until a fix is available. labels Apr 26, 2020
@sdzhepa sdzhepa added the Triage: Dev.Experience Issue related to Developer Experience and needs help with Triage to Confirm or Reject it label May 6, 2020
@VladimirZaets VladimirZaets added the Priority: P2 A defect with this priority could have functionality issues which are not to expectations. label Aug 4, 2020
@magento-engcom-team magento-engcom-team added Issue: Format is valid Gate 1 Passed. Automatic verification of issue format passed and removed Issue: Format is not valid Gate 1 Failed. Automatic verification of issue format is failed labels Aug 11, 2020
@engcom-Alfa engcom-Alfa added Triage: Done Has been reviewed and prioritized during Triage with Product Managers Reproduced on 2.4.x The issue has been reproduced on latest 2.4-develop branch Issue: Confirmed Gate 3 Passed. Manual verification of the issue completed. Issue is confirmed labels Aug 11, 2020
@ghost ghost removed the Triage: Dev.Experience Issue related to Developer Experience and needs help with Triage to Confirm or Reject it label Aug 11, 2020
@magento-engcom-team
Copy link
Contributor

@engcom-Alfa Thank you for verifying the issue.

Unfortunately, not enough information was provided to acknowledge ticket. Please consider adding the following:

  • Add "Component: " label(s) to this ticket based on verification result. If uncertain, you may follow the best guess

Once all required information is added, please add label "Issue: Confirmed" again.
Thanks!

@magento-engcom-team magento-engcom-team removed the Issue: Confirmed Gate 3 Passed. Manual verification of the issue completed. Issue is confirmed label Aug 11, 2020
@ghost ghost moved this from PR In Progress to Ready for QA in Community Backlog Aug 11, 2020
@engcom-Alfa engcom-Alfa added Component: CacheInvalidate Progress: PR in progress Issue: Confirmed Gate 3 Passed. Manual verification of the issue completed. Issue is confirmed and removed Progress: ready for QA labels Aug 11, 2020
@magento-engcom-team
Copy link
Contributor

✅ Confirmed by @engcom-Alfa
Thank you for verifying the issue. Based on the provided information internal tickets MC-36618 were created

Issue Available: @engcom-Alfa, You will be automatically unassigned. Contributors/Maintainers can claim this issue to continue. To reclaim and continue work, reassign the ticket to yourself.

@magento-engcom-team magento-engcom-team added the Issue: Ready for Work Gate 4. Acknowledged. Issue is added to backlog and ready for development label Aug 11, 2020
@ghost ghost moved this from Ready for QA to Ready for Dev in Community Backlog Aug 11, 2020
@magento-engcom-team magento-engcom-team added the Fixed in 2.4.x The issue has been fixed in 2.4-develop branch label Aug 13, 2020
@ghost ghost moved this from Ready for Dev to Done (last 30 days) in Community Backlog Aug 13, 2020
magento-engcom-team added a commit that referenced this issue Aug 13, 2020
…ix incorrect tag splitting #26256

 - Merge Pull Request #26256 from moloughlin/magento2:fix/cache_invalidate_incorrect_tag_splitting
 - Merged commits:
   1. e212301
   2. 4c22303
   3. fc2ce73
   4. a9d376d
   5. 5e69e82
   6. 479c0cc
   7. d0ef6ae
   8. 85b3ffd
   9. 116c191
   10. 0926f5c
   11. ffb1174
   12. 99b26a4
   13. a19274e
magento-engcom-team pushed a commit that referenced this issue Aug 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: CacheInvalidate Fixed in 2.4.x The issue has been fixed in 2.4-develop branch Issue: Confirmed Gate 3 Passed. Manual verification of the issue completed. Issue is confirmed Issue: Format is valid Gate 1 Passed. Automatic verification of issue format passed Issue: Ready for Work Gate 4. Acknowledged. Issue is added to backlog and ready for development Priority: P2 A defect with this priority could have functionality issues which are not to expectations. Reproduced on 2.4.x The issue has been reproduced on latest 2.4-develop branch Severity: S1 Affects critical data or functionality and forces users to employ a workaround. Triage: Done Has been reviewed and prioritized during Triage with Product Managers
Projects
No open projects
Community Backlog
  
Done (last 30 days)
6 participants