You are here: Foswiki>Tasks Web>Item12915 (06 Nov 2018, MichaelDaum)Edit Attach

Item12915: The PageCache::genVariationKey() fails to consider the action (view or rest) when calculating a cache key.

pencil
Priority: Urgent
Current State: Closed
Released In: 1.2.0
Target Release: minor
Applies To: Engine
Component: PageCache
Branches: trunk
Reported By: GeorgeClark
Waiting For:
Last Change By: MichaelDaum
While trying to debug the FoswikiOrgPlugin/githubpush, it returns the Main/WebHome cached page for the logged in user instead of invoking the REST handler.

I'm not sure how REST should be cached, but since REST requests don't really have a web/topic associated, the cache if any at all should be based upon the subject/verb.

I'm going to temporarily disable the rest cache function until this gets worked out.

-- GeorgeClark - 27 May 2014

Not a good idea. REST calls indeed normally have a proper location where they should be evaluated. True, does not hold for every REST call but most I know of operate on data available on a certain location.

For example, when using RenderPlugin to generate an expensive dashboard, I explicitly render parts of the page using a REST handler. Another example is fetching an expensive JSON object. These all should be properly page-cached by Foswiki and invalidated if new data is available.

If you don't want page caching, either disable it for this specific topic or add a t=%GMTIME{"$epoch"}% or refresh=cache to the parameter list of the REST call. Most client-side apps do that in one way or the other to prevent browser-side caching.

Sorry, but I have to revert your checkin. There is actually no bug here.

-- MichaelDaum - 27 May 2014

It's not a topic. It's a rest handler that doesn't want / need / use a topic location. Foswiki::UI::Rest so helpfully sets a default location.
        # No topic specified, but we still have to set a topic to stop
        # plugins being passed the subject and verb in place of a topic.
        Foswiki::Func::popTopicContext();
        Foswiki::Func::pushTopicContext( $Foswiki::cfg{UsersWebName},
            $Foswiki::cfg{HomeTopicName} );

And right after that, the cache code asks... is there a cache entry. Yup, sure Main/WebHome has a cache entry from the last view request, but meh.. Good enough. It responds with the cached page, and stops there. Shouldn't it check to see if "bin/rest" has a specific cache entry rather than grabbing "bin/view" for the response.

I cannot understand why a bin/rest script should return output from bin/view. Okay... if it should cache the bin/rest json output, fine. But not the output from a totally unrelated topics, accessed with a completely different script.

My fix was done because I'm debugging this particular issue directly on trunk.foswiki.org and I didn't want to break SVN by editing files directly. Fine to revert. I expected that. But I am absolutely not convinced that this is "No Action" Setting back to new as a Release Blocker.

-- GeorgeClark - 28 May 2014

How can I reproduce this? Here's a minimal rest handler:

  Foswiki::Func::registerRESTHandler(
    'test',
    sub {
      return "foo\n\n";
    },
    validate     => 0,  
    authenticate => 0, 
  );

It produces foo ... and the page cache rightfully caches foo. Whenever I change the code to return foo2 will it still return foo. There's no surprise here.

Could you please provide a similar example implementation of a rest handler that produces wrong results as you've been experiencing them?

About rest and topic locations: for everything calling Foswiki web and topic variables require a valid value. If no location could be determined from the url or url parameters will it instantiate sufficient defaults.

-- MichaelDaum - 28 May 2014

The plugin where I'm recreating this is FoswikiOrgPlugin.

The plugin always generates it's own output and returns undef. It never returns anything, so the the cache will never be populated. (it isn't actually very useful, since it always will fail with a 4xx - it needs a post with some hmac headers from github, but I'm using it with get just for some debugging purposes.)

I think that the problem is that if there are no URL params or other identifying attributes to generate a unique cache key, a collision occurs. And the scriptname is not considered in the key generation. So bin/view/Main/WebHome and bin/rest/FoswikiOrgPlugin/githubpush generate a collision in the cache.

It's probably a real corner case, most REST handlers would have URL parameters or be target of a POST. But it was still a very surprising result, and caused me no end of confusion. I suspect a fix would be to add the script name as part of the key generation.

The reason authentication makes a difference, is that we don't allow guest access to bin/view, so the guest user will never have a cache entry for Main/WebHome.

-- GeorgeClark - 28 May 2014

Ah... and one more side effect showing the cache collision:

So if bin/view and bin/rest have the same URL parameters, you also get a collision.

-- GeorgeClark - 28 May 2014

I've run into this for the default Main.WebHome, but this can happen for any topic.

Since the topic urlparam is not included in the cache key calculation, it's not needed when priming the cache.

So this is even simpler than your example. It demonstrates the collision without even implementing a plugin or rest handler.

-- GeorgeClark - 28 May 2014

The 1st 4 characters of the Action (script) have been added to the variationKey. Closing task.

-- GeorgeClark - 02 Jun 2014

 

ItemTemplate edit

Summary The PageCache::genVariationKey() fails to consider the action (view or rest) when calculating a cache key.
ReportedBy GeorgeClark
Codebase trunk
SVN Range
AppliesTo Engine
Component PageCache
Priority Urgent
CurrentState Closed
WaitingFor
Checkins distro:8f7c33ea9e38 distro:2d0737d1b259 distro:05343fe61fd5
TargetRelease minor
ReleasedIn 1.2.0
CheckinsOnBranches trunk
trunkCheckins distro:8f7c33ea9e38 distro:2d0737d1b259 distro:05343fe61fd5
Release01x01Checkins
Topic revision: r12 - 06 Nov 2018, MichaelDaum
The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. See Copyright Statement. Creative Commons License    Legal Imprint    Privacy Policy