01401: PageExists cache $PageExistsCache becomes stale after new page created

Summary: PageExists cache $PageExistsCache becomes stale after new page created
Created: 2017-01-09 16:33
Status: Closed, added for 2.2.94
Category: Bug
From: Peter Kay
Assigned:
Priority: 3
Version: 2.2.93
OS:

Description: If you run PageExists("Main.Test"); and then use UpdatePage to create Main.Test, any future calls to PageExists will still return false, because $PageExistsCache has not been updated after UpdatePage.

The reverse might also happen: if a page is deleted after PageExists() is called, the cache will show the page still exists.

Peter Kay January 09, 2017, at 04:33 PM

One easy solution would be to add

function ClearPageExistsCache($pagename) {

  unset($GLOBALS['PageExistsCache'][$pagename]);

}

And add the line "ClearPageExistsCache($pagename);" at the very end of either PostPage() or SaveAttributes().

Peter Kay January 09, 2017, at 04:44 PM

After reviewing the entry, I may have to decline this feature request. Currently nothing prevents the core PmWiki to function properly, only a recipe may require the additional feature. Also, a recipe may have a number of different ways to create or delete pages: UpdatePage(), PostPage(), WritePage(), $WikiDir->delete() or their own implementation; a custom PageStore class may do it in more ways; additionally, UpdatePage calls two functions that may create pages: AutoCreateTargets() and PostRecentChanges(). For this reason, I'll leave it to the recipe developer who needs to clear the cache to do it when necessary. If you feel this should be documented in some way, feel free to do it. --Petko January 11, 2017, at 12:39 PM

I've traced every write I can find in the core pmwiki, and except for special files (page cache, last-modified, etc), all the file creation goes through the PageStore->write function. Adding ClearPageExistsCache($pagename); right before the final PCache would catch every non-cookbook way of writing a file. Likewise, the only way a regular page gets deleted is via the PageStore delete() function. A similar ClearPageExistsCache($pagename); at the end of that function would cover everything. I would be happy to add some documentation for anyone wanting to write files on their own, but I suspect anyone following the given PageStore code would immediately grasp why the PageExistsCache is cleared.

I am aware the core functioning doesn't need the change, but someone writing a cookbook would like to be able to use the PageExists() function with confidence. The change would add very minimal overhead for core functioning, while allowing easier and safer expansions via recipes.

At the very least, the function ClearPageExistsCache should be created: as noted at line 1189 of pmwiki.php, $PageExistsCache might change or disappear someday. A function with a reliable name would ensure future functionality, and would be easily added to documentation for anyone using UpdagePage() or the PageStore functions. Alternately, the global variable $PageExistsCache could be enshrined as is for future use. Peter Kay January 23, 2017, at 10:38 PM

Fair enough, the cache will be cleared for the next version; no function, simple calls to unset the variables in write() and delete(). --Petko January 31, 2017, at 02:41 PM