Support » Plugin: LiteSpeed Cache » Litespeed Cache API – Purging Specific User’s Private Cache for ESI Shortcode

  • Resolved Jacob Hill

    (@tekfused)


    Hello,

    I was reading this article about using ESI with WP shortcodes – specifically the content under the header, “Get the Plugin Author Involved” – and I’m wondering if there is a way to purge the ESI shortcode private cache for a specific user.

    method_exists( 'LiteSpeed_Cache_API', 'purge' ) && LiteSpeed_Cache_API::purge( 'esi.myeventlist' ) ;

    This code purges the ESI shortcode, which is good, but that would assumedly blow away all the cached content for all users for that ESI block. Is there a way to purge the ESI block’s cache for a specific user using the API?

    Thanks in advance!

Viewing 11 replies - 1 through 11 (of 11 total)
  • Plugin Support stanley@litespeed

    (@stanleylitespeed)

    Hi @tekfused, you can use LiteSpeed_Cache_API::purge_private for purging a private cache by a tag.

    Jacob Hill

    (@tekfused)

    Hello @stanleylitespeed, thanks. I assume that would clear the private cache for all users. Is there any way to pass a user ID (Or another identifier) to this so that it clears the private cache for a specific user?

    • This reply was modified 4 months ago by Jacob Hill.
    • This reply was modified 4 months ago by Jacob Hill.
    Plugin Support stanley@litespeed

    (@stanleylitespeed)

    Hi @tekfused, on your hook_tpl_esi function, you can add LiteSpeed_Cache_API::tag_add(YOUR_TAG_HERE) ; to add a specific tag for each ESI cache, then you can use purge the cache by this tag.

    Hi @stanleylitespeed, that is perfect, thank you very much! In this case, I’ll use a tag similar to “${user_email}.${esitag}” and then clear it by using that tag as needed.

    Hello, @stanleylitespeed! I’m getting back to this, and want to make sure I’m purging the block correctly. I’ve been testing this out, and in my tests, I’ve noticed that if I expire the block using a very short TTL (10 seconds for example), it recalculates instantly after it expires, but when I purge it via the tag, it doesn’t purge instantly (I have to wait 30 seconds before refreshing the page, otherwise I receive the stale block with the JS redirect).

    Here is the code:

    // Initializes the ESI block.
    add_action( 'wp_head', 'esi_subscription_check' );
    function esi_subscription_check()
    {
        echo LiteSpeed_Cache_API::esi_url( 'subscription_check_esi', 'Subscription Check ESI', array(), 'private' ) ;
    }
    
    // Enables the ESI block and hooks to a function.
    LiteSpeed_Cache_API::hook_tpl_esi('subscription_check_esi', 'subscription_check_esi_function' ) ;
    function subscription_check_esi_function( $param )
    {
        // Sets the TTL for this ESI block.
        LiteSpeed_Cache_API::set_ttl( 86400 ) ;
        
        // Tags the ESI cache with the current user's ID so the entire user cache doesn't need to be changed later.
        $user_id = get_current_user_id();
        LiteSpeed_Cache_API::tag_add( 'subscription_check_' . $user_id ) ;
        ...
        do_stuff();
    }
    
    function do_stuff()
    {
        $user_id = ...
        LiteSpeed_Cache_API::purge_private( 'subscription_check_' . $user_ID ) ;
    }

    In the do_stuff() function, am I using the currect tag identifier? Should it be 'esi.subscription_check_' . $user_ID?

    Thanks in advance!

    Jake

    • This reply was modified 3 months, 1 week ago by Jacob Hill.
    • This reply was modified 3 months, 1 week ago by Jacob Hill.
    • This reply was modified 3 months, 1 week ago by Jacob Hill.
    Plugin Support stanley@litespeed

    (@stanleylitespeed)

    Hi @tekfused, could you try to set the ESI cache control as private,no-vary like:

    echo LiteSpeed_Cache_API::esi_url( 'subscription_check_esi', 'Subscription Check ESI', array(), 'private,no-vary' ) ;

    to prevent the cache mixed with other users in the same role?

    Thanks, @stanleylitespeed! I tried adding ‘no-vary’, but that didn’t fix the issue. I actually had to change the purge action in the do_stuff() function to LiteSpeed_Cache_API::purge( 'subscription_check_' . $user_ID ) ;

    It is odd because I’m declaring it as a private block, yet the private_purge action doesn’t work. I have debug mode enabled, and here is the output at the top of the page’s HTML:

    <!-- Block generated by LiteSpeed Cache 2.9.8.7 on 2019-10-15 21:20:59 -->
    <!-- X-LiteSpeed-Cache-Control: private,no-vary,max-age=86400 -->
    <!-- X-LiteSpeed-Tag: 161_tag_priv,public:161_ESI,public:161_ESI.subscription_check_esi,public:161_subscription_check_676,public:161_ -->
    <!-- Object Cache  [total] 5229 [hit_incall] 5036 [hit] 93 [miss_incall] 30 [miss] 70 [set] 108 -->

    As you can see, it appears that Litespeed is creating the ESI block as a public block opposed to a private block. Not sure why? It appears to function in my testing as a private block, even though the private_purge action doesn’t work.

    Here is the updated code:

    // Initializes the ESI block.
    add_action( 'wp_head', 'esi_subscription_check' );
    function esi_subscription_check()
    {
        echo LiteSpeed_Cache_API::esi_url( 'subscription_check_esi', 'Subscription Check ESI', array(), 'private,no-vary' ) ;
    }
    
    // Enables the ESI block and hooks to a function.
    LiteSpeed_Cache_API::hook_tpl_esi('subscription_check_esi', 'subscription_check_esi_function' ) ;
    function subscription_check_esi_function( $param )
    {
        // Sets the TTL for this ESI block.
        LiteSpeed_Cache_API::set_ttl( 86400 ) ;
        
        // Tags the ESI cache with the current user's ID so the entire user cache doesn't need to be changed later.
        $user_id = get_current_user_id();
        LiteSpeed_Cache_API::tag_add( 'subscription_check_' . $user_id ) ;
        ...
        do_stuff();
    }
    
    function do_stuff()
    {
        ...
        $user_id = ...
        LiteSpeed_Cache_API::purge( 'subscription_check_' . $user_ID ) ;
    }

    Thoughts?

    Plugin Support stanley@litespeed

    (@stanleylitespeed)

    Hi @tekfused, sorry for my mistake, if you need to add a tag for private cache, please use: LiteSpeed_Cache_API::add_private() instead.

    Hi @stanleylitespeed,

    Thanks for that. I did try this, but when I set the tag to private, it won’t clear the ESI block. I believe there is another issue here – take a look at this excerpt from the code in my previous post:

    <!-- X-LiteSpeed-Tag: 161_tag_priv,public:161_ESI,public:161_ESI.subscription_check_esi,public:161_subscription_check_676,public:161_ -->

    You’ll see public:161_ESI.subscription_check_esi which is actually the ESI block (Not the tag), which should be private, but it is listed as public.

    Again, here is the ESI declaration:

    function esi_subscription_check()
    {
        echo LiteSpeed_Cache_API::esi_url( 'subscription_check_esi', 'Subscription Check ESI', array(), 'private,no-vary' ) ;
    }

    It appears that the ESI block is acting like a private block, in that it is regenerated and maintained separately for each user, but I’m not sure why it is being shown as public in the HTML debug output above.

    Thanks in advance!

    Jake

    Plugin Support stanley@litespeed

    (@stanleylitespeed)

    Hi @tekfused, is that X-LiteSpeed-Tag showing on a logged-in user? Could you send us a debug log after you purge and reload the page? You can also join our Slack channel to let us know how to reproduce the issue on your site.

    Jacob Hill

    (@tekfused)

    Hi @stanleylitespeed, yes, it shows for logged in users, and for users who have not logged in. I submitted a ticket with the information you requested.

    • This reply was modified 3 months ago by Jacob Hill.
Viewing 11 replies - 1 through 11 (of 11 total)
  • You must be logged in to reply to this topic.