mirror of
https://github.com/sbrl/Pepperminty-Wiki.git
synced 2024-12-22 13:45:02 +00:00
Add parser output caching layer
This commit is contained in:
parent
d51c3f163f
commit
2974966c07
4 changed files with 70 additions and 13 deletions
|
@ -13,6 +13,11 @@ This file holds the changelog for Pepperminty Wiki. This is the master list of t
|
|||
- All alternative formats for this action are advertised in via a `<link rel="alternate" />` in the `<head>` now
|
||||
- Added `count` and `offset` GET parameters to `recent-changes` action.
|
||||
- Added new `find_revisionid_timestamp()` function to `feature-recent-changes` module.
|
||||
- Added new parser output caching system!
|
||||
- 2 new settings have been added: `parser_cache` and `parser_cache_min_size`
|
||||
- Uses a hash of the content, the _Pepperminty Wiki_ version, and the parser name as the cache id - so it should never serve stale content (unless you're actively working on particular areas of _Pepperminty Wiki_'s codebase of course)
|
||||
- Useful for longer pages
|
||||
- `parser_cache_min_size` may need tuning for your specific installation (lower it if you regularly use features that are slow to parse; raise if it's the opposite)
|
||||
|
||||
### Changed
|
||||
- Completely reworked the README to refactor out the documentation to its [own static site](https://starbeamrainbowlabs.com/labs/peppermint/_docpress/)
|
||||
|
|
|
@ -41,6 +41,8 @@ $guiConfig = <<<'GUICONFIG'
|
|||
"anonedits": { "type": "checkbox", "description": "Whether users who aren't logged in are allowed to edit your wiki.", "default": false },
|
||||
"maxpagesize": { "type": "number", "description": "The maximum page size in characters.", "default": 135000 },
|
||||
"parser": { "type": "text", "description": "The parser to use when rendering pages. Defaults to an extended version of parsedown (http://parsedown.org/)", "default": "parsedown" },
|
||||
"parser_cache": { "type": "checkbox", "description": "Whether parser output should be cached to speed things up. The cache directory is <code>._cache</code> in the data directory - delete it if you experience issues (unlikely).", "default": true },
|
||||
"parser_cache_min_size": { "type": "number", "description": "The minimum size a source string must be (in bytes) before it's considered eligible for caching.", "default": 1024 },
|
||||
"interwiki_index_location": { "type": "text", "description": "The location to find the interwiki wiki definition file, which contains a list of wikis along with their names, prefixes, and root urls. May be a URL, or simply a file path - as it's passed to file_get_contents(). If left blank, interwiki link parsing is disabled.", "default": null },
|
||||
"clean_raw_html": { "type": "checkbox", "description": "Whether page sources should be cleaned of HTML before rendering. It is STRONGLY recommended that you keep this option turned on.", "default": true},
|
||||
"enable_math_rendering": { "type": "checkbox", "description": "Whether to enable client side rendering of mathematical expressions with MathJax (https://www.mathjax.org/). Math expressions should be enclosed inside of dollar signs ($). Turn off if you don't use it.", "default": true},
|
||||
|
@ -411,7 +413,7 @@ if($settings->sessionprefix == "auto")
|
|||
/////////////////////////////////////////////////////////////////////////////
|
||||
/** The version of Pepperminty Wiki currently running. */
|
||||
$version = "v0.18-dev";
|
||||
$commit = "c120902cda82e3efcd32d071ad8993c06fdc79ac";
|
||||
$commit = "d51c3f163fbaeed63e8b0109e684a810d2a4604a";
|
||||
/// Environment ///
|
||||
/** Holds information about the current request environment. */
|
||||
$env = new stdClass();
|
||||
|
@ -2144,19 +2146,43 @@ function add_parser($name, $parser_code)
|
|||
* into HTML.
|
||||
* The specified parser may (though it's unlikely) render it to other things.
|
||||
* @package core
|
||||
* @param string $source The source to render.
|
||||
* @return string The source rendered to HTML.
|
||||
* @param string $source The source to render.
|
||||
* @param string $use_cache Whether to use the on-disk cache. Has no effect if parser caching is disabled in peppermint.json, or the source string is too small.
|
||||
* @return string The source rendered to HTML.
|
||||
*/
|
||||
function parse_page_source($source) {
|
||||
global $settings, $parsers;
|
||||
function parse_page_source($source, $use_cache = true) {
|
||||
global $settings, $paths, $parsers, $version;
|
||||
$start_time = microtime(true);
|
||||
|
||||
if(!$settings->parser_cache || strlen($source) < $settings->parser_cache_min_size) $use_cache = false;
|
||||
|
||||
if(!isset($parsers[$settings->parser]))
|
||||
exit(page_renderer::render_main("Parsing error - $settings->sitename", "<p>Parsing some page source data failed. This is most likely because $settings->sitename has the parser setting set incorrectly. Please contact <a href='mailto:" . hide_email($settings->admindetails_email) . "'>" . $settings->admindetails_name . "</a>, your $settings->sitename Administrator."));
|
||||
|
||||
|
||||
/* Not needed atm because escaping happens when saving, not when rendering *
|
||||
if($settings->clean_raw_html)
|
||||
$source = htmlentities($source, ENT_QUOTES | ENT_HTML5);
|
||||
*/
|
||||
return $parsers[$settings->parser]($source);
|
||||
|
||||
$cache_id = str_replace(["+","/"], ["-","_"], base64_encode(hash("sha256", "$version|$settings->parser|$source", true)));
|
||||
$cache_file = "{$paths->cache_directory}/{$cache_id}.html";
|
||||
|
||||
$result = null;
|
||||
if($use_cache && file_exists($cache_file)) {
|
||||
$result = file_get_contents($cache_file);
|
||||
$result .= "\n<!-- cache: hit, id: $cache_id, took: " . round((microtime(true) - $start_time)*1000, 5) . "ms -->\n";
|
||||
}
|
||||
if($result == null) {
|
||||
$result = $parsers[$settings->parser]($source);
|
||||
// If we should use the cache and we failed to write to it, warn the admin.
|
||||
// It's not terribible if we can't write to the cache directory (so we shouldn't stop dead & refuse service), but it's still of concern.
|
||||
if($use_cache && !file_put_contents($cache_file, $result))
|
||||
error_log("[Pepperminty Wiki] Warning: Failed to write to cache file $cache_file.");
|
||||
|
||||
$result .= "\n<!-- cache: " . ($use_cache ? "miss" : "n/a") . ", id: $cache_id, took: " . round((microtime(true) - $start_time)*1000, 5) . "ms -->\n";
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Function to
|
||||
|
|
36
core.php
36
core.php
|
@ -1743,19 +1743,43 @@ function add_parser($name, $parser_code)
|
|||
* into HTML.
|
||||
* The specified parser may (though it's unlikely) render it to other things.
|
||||
* @package core
|
||||
* @param string $source The source to render.
|
||||
* @return string The source rendered to HTML.
|
||||
* @param string $source The source to render.
|
||||
* @param string $use_cache Whether to use the on-disk cache. Has no effect if parser caching is disabled in peppermint.json, or the source string is too small.
|
||||
* @return string The source rendered to HTML.
|
||||
*/
|
||||
function parse_page_source($source) {
|
||||
global $settings, $parsers;
|
||||
function parse_page_source($source, $use_cache = true) {
|
||||
global $settings, $paths, $parsers, $version;
|
||||
$start_time = microtime(true);
|
||||
|
||||
if(!$settings->parser_cache || strlen($source) < $settings->parser_cache_min_size) $use_cache = false;
|
||||
|
||||
if(!isset($parsers[$settings->parser]))
|
||||
exit(page_renderer::render_main("Parsing error - $settings->sitename", "<p>Parsing some page source data failed. This is most likely because $settings->sitename has the parser setting set incorrectly. Please contact <a href='mailto:" . hide_email($settings->admindetails_email) . "'>" . $settings->admindetails_name . "</a>, your $settings->sitename Administrator."));
|
||||
|
||||
|
||||
/* Not needed atm because escaping happens when saving, not when rendering *
|
||||
if($settings->clean_raw_html)
|
||||
$source = htmlentities($source, ENT_QUOTES | ENT_HTML5);
|
||||
*/
|
||||
return $parsers[$settings->parser]($source);
|
||||
|
||||
$cache_id = str_replace(["+","/"], ["-","_"], base64_encode(hash("sha256", "$version|$settings->parser|$source", true)));
|
||||
$cache_file = "{$paths->cache_directory}/{$cache_id}.html";
|
||||
|
||||
$result = null;
|
||||
if($use_cache && file_exists($cache_file)) {
|
||||
$result = file_get_contents($cache_file);
|
||||
$result .= "\n<!-- cache: hit, id: $cache_id, took: " . round((microtime(true) - $start_time)*1000, 5) . "ms -->\n";
|
||||
}
|
||||
if($result == null) {
|
||||
$result = $parsers[$settings->parser]($source);
|
||||
// If we should use the cache and we failed to write to it, warn the admin.
|
||||
// It's not terribible if we can't write to the cache directory (so we shouldn't stop dead & refuse service), but it's still of concern.
|
||||
if($use_cache && !file_put_contents($cache_file, $result))
|
||||
error_log("[Pepperminty Wiki] Warning: Failed to write to cache file $cache_file.");
|
||||
|
||||
$result .= "\n<!-- cache: " . ($use_cache ? "miss" : "n/a") . ", id: $cache_id, took: " . round((microtime(true) - $start_time)*1000, 5) . "ms -->\n";
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Function to
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
"anonedits": { "type": "checkbox", "description": "Whether users who aren't logged in are allowed to edit your wiki.", "default": false },
|
||||
"maxpagesize": { "type": "number", "description": "The maximum page size in characters.", "default": 135000 },
|
||||
"parser": { "type": "text", "description": "The parser to use when rendering pages. Defaults to an extended version of parsedown (http://parsedown.org/)", "default": "parsedown" },
|
||||
"parser_cache": { "type": "checkbox", "description": "Whether parser output should be cached to speed things up. The cache directory is <code>._cache</code> in the data directory - delete it if you experience issues (unlikely).", "default": true },
|
||||
"parser_cache_min_size": { "type": "number", "description": "The minimum size a source string must be (in bytes) before it's considered eligible for caching.", "default": 1024 },
|
||||
"interwiki_index_location": { "type": "text", "description": "The location to find the interwiki wiki definition file, which contains a list of wikis along with their names, prefixes, and root urls. May be a URL, or simply a file path - as it's passed to file_get_contents(). If left blank, interwiki link parsing is disabled.", "default": null },
|
||||
"clean_raw_html": { "type": "checkbox", "description": "Whether page sources should be cleaned of HTML before rendering. It is STRONGLY recommended that you keep this option turned on.", "default": true},
|
||||
"enable_math_rendering": { "type": "checkbox", "description": "Whether to enable client side rendering of mathematical expressions with MathJax (https://www.mathjax.org/). Math expressions should be enclosed inside of dollar signs ($). Turn off if you don't use it.", "default": true},
|
||||
|
|
Loading…
Reference in a new issue