[speed_hax] extract SPEED_HAX tweaks to extension

This commit is contained in:
discomrade 2024-06-14 13:37:24 +00:00
parent 60f96fa128
commit 350b44f250
15 changed files with 120 additions and 30 deletions

View file

@ -84,7 +84,7 @@ class Search
*/
private static function find_images_internal(int $start = 0, ?int $limit = null, array $tags = []): \FFSPHP\PDOStatement
{
global $database, $user;
global $config, $database, $user;
if ($start < 0) {
$start = 0;
@ -93,9 +93,10 @@ class Search
$limit = 1;
}
if (SPEED_HAX) {
if (!$user->can(Permissions::BIG_SEARCH) and count($tags) > 3) {
throw new PermissionDenied("Anonymous users may only search for up to 3 tags at a time");
if (Extension::is_enabled(SpeedHaxInfo::KEY) && $config->get_int(SpeedHaxConfig::BIG_SEARCH) > 0) {
$anon_limit = $config->get_int(SpeedHaxConfig::BIG_SEARCH);
if (!$user->can(Permissions::BIG_SEARCH) and count($tags) > $anon_limit) {
throw new PermissionDenied("Anonymous users may only search for up to $anon_limit tags at a time");
}
}
@ -182,15 +183,16 @@ class Search
*/
public static function count_images(array $tags = []): int
{
global $cache, $database;
global $cache, $config, $database;
$tag_count = count($tags);
// SPEED_HAX ignores the fact that extensions can add img_conditions
// speed_hax ignores the fact that extensions can add img_conditions
// even when there are no tags being searched for
if (SPEED_HAX && $tag_count === 0) {
$speed_hax = (Extension::is_enabled(SpeedHaxInfo::KEY) && $config->get_bool(SpeedHaxConfig::LIMIT_COMPLEX));
if ($speed_hax && $tag_count === 0) {
// total number of images in the DB
$total = self::count_total_images();
} elseif (SPEED_HAX && $tag_count === 1 && !preg_match("/[:=><\*\?]/", $tags[0])) {
} elseif ($speed_hax && $tag_count === 1 && !preg_match("/[:=><\*\?]/", $tags[0])) {
if (!str_starts_with($tags[0], "-")) {
// one positive tag - we can look that up directly
$total = self::count_tag($tags[0]);
@ -207,7 +209,7 @@ class Search
[$tag_conditions, $img_conditions, $order] = self::terms_to_conditions($tags);
$querylet = self::build_search_querylet($tag_conditions, $img_conditions, null);
$total = (int)$database->get_one("SELECT COUNT(*) AS cnt FROM ($querylet->sql) AS tbl", $querylet->variables);
if (SPEED_HAX && $total > 5000) {
if ($speed_hax && $total > 5000) {
// when we have a ton of images, the count
// won't change dramatically very often
$cache->set($cache_key, $total, 3600);

View file

@ -20,7 +20,7 @@ abstract class Permissions
public const CHANGE_USER_SETTING = "change_user_setting";
public const CHANGE_OTHER_USER_SETTING = "change_other_user_setting";
/** search for more than 3 tags at once (only applies if SPEED_HAX is active) */
/** search for more than 3 tags at once (only applies if Speed Hax is active) */
public const BIG_SEARCH = "big_search";
/** enable or disable extensions */

View file

@ -19,18 +19,19 @@ $_shm_event_listeners = [];
function _load_event_listeners(): void
{
global $_shm_event_listeners;
global $_shm_event_listeners, $config;
$ver = preg_replace("/[^a-zA-Z0-9\.]/", "_", VERSION);
$key = md5(Extension::get_enabled_extensions_as_string());
$speed_hax = (Extension::is_enabled(SpeedHaxInfo::KEY) && $config->get_bool(SpeedHaxConfig::CACHE_EVENT_LISTENERS));
$cache_path = data_path("cache/event_listeners/el.$ver.$key.php");
if (SPEED_HAX && file_exists($cache_path)) {
if ($speed_hax && file_exists($cache_path)) {
require_once($cache_path);
} else {
_set_event_listeners();
if (SPEED_HAX) {
if ($speed_hax) {
_dump_event_listeners($_shm_event_listeners, $cache_path);
}
}

View file

@ -14,7 +14,7 @@ namespace Shimmie2;
* Do NOT change them in this file. These are the defaults only!
*
* Example:
* define("SPEED_HAX", true);
* define("DEBUG", true);
*/
function _d(string $name, mixed $value): void
@ -29,7 +29,6 @@ _d("DATABASE_TIMEOUT", 10000); // int Time to wait for each statement to c
_d("CACHE_DSN", null); // string cache connection details
_d("DEBUG", false); // boolean print various debugging details
_d("COOKIE_PREFIX", 'shm'); // string if you run multiple galleries with non-shared logins, give them different prefixes
_d("SPEED_HAX", false); // boolean do some questionable things in the name of performance
_d("WH_SPLITS", 1); // int how many levels of subfolders to put in the warehouse
_d("VERSION", "2.12.0-alpha"); // string shimmie version
_d("TIMEZONE", null); // string timezone

View file

@ -55,7 +55,7 @@ function make_link(?string $page = null, ?string $query = null, ?string $fragmen
$parts = [];
$install_dir = get_base_href();
if (SPEED_HAX || $config->get_bool(SetupConfig::NICE_URLS, false)) {
if ($config->get_bool(SetupConfig::NICE_URLS, false)) {
$parts['path'] = "$install_dir/$page";
} else {
$parts['path'] = "$install_dir/index.php";

View file

@ -236,7 +236,8 @@ class CommentList extends Extension
if ($event->page_matches("comment/list", paged: true)) {
$threads_per_page = 10;
$where = SPEED_HAX ? "WHERE posted > now() - interval '24 hours'" : "";
$speed_hax = (Extension::is_enabled(SpeedHaxInfo::KEY) && $config->get_bool(SpeedHaxConfig::CACHE_TAG_LISTS));
$where = $speed_hax ? "WHERE posted > now() - interval '24 hours'" : "";
$total_pages = cache_get_or_set("comment_pages", fn () => (int)ceil($database->get_one("
SELECT COUNT(c1)

View file

@ -43,11 +43,12 @@ class Index extends Extension
$page_number = $event->get_iarg('page_num', 1);
$page_size = $config->get_int(IndexConfig::IMAGES);
$speed_hax = (Extension::is_enabled(SpeedHaxInfo::KEY) && $config->get_bool(SpeedHaxConfig::FAST_PAGE_LIMIT));
$fast_page_limit = 500;
$ua = $_SERVER["HTTP_USER_AGENT"] ?? "No UA";
if (
SPEED_HAX
$speed_hax
&& (
str_contains($ua, "Googlebot")
|| str_contains($ua, "YandexBot")
@ -63,7 +64,7 @@ class Index extends Extension
$fast_page_limit = 10;
}
if (SPEED_HAX && $page_number > $fast_page_limit && !$user->can("big_search")) {
if ($speed_hax && $page_number > $fast_page_limit && !$user->can("big_search")) {
throw new PermissionDenied(
"Only $fast_page_limit pages of results are searchable - " .
"if you want to find older results, use more specific search terms"
@ -71,12 +72,12 @@ class Index extends Extension
}
$total_pages = (int)ceil(Search::count_images($search_terms) / $config->get_int(IndexConfig::IMAGES));
if (SPEED_HAX && $total_pages > $fast_page_limit && !$user->can("big_search")) {
if ($speed_hax && $total_pages > $fast_page_limit && !$user->can("big_search")) {
$total_pages = $fast_page_limit;
}
$images = null;
if (SPEED_HAX) {
if (Extension::is_enabled(SpeedHaxInfo::KEY) && $config->get_bool(SpeedHaxConfig::CACHE_FIRST_FEW)) {
if ($count_search_terms === 0 && ($page_number < 10)) {
// extra caching for the first few post/list pages
$images = cache_get_or_set(

View file

@ -31,7 +31,7 @@ class RSSImages extends Extension
$search_terms = Tag::explode($event->get_arg('search', ""));
$page_number = $event->get_iarg('page_num', 1);
$page_size = $config->get_int(IndexConfig::IMAGES);
if (SPEED_HAX && $page_number > 9) {
if (Extension::is_enabled(SpeedHaxInfo::KEY) && $config->get_bool(SpeedHaxConfig::RSS_LIMIT) && $page_number > 9) {
return;
}
$images = Search::find_images(($page_number - 1) * $page_size, $page_size, $search_terms);

33
ext/speed_hax/info.php Normal file
View file

@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace Shimmie2;
class SpeedHaxInfo extends ExtensionInfo
{
public const KEY = "speed_hax";
public string $key = self::KEY;
public string $name = "Speed Hax";
public array $authors = [self::SHISH_NAME => self::SHISH_EMAIL, "jgen" => "jgen.tech@gmail.com", "Matthew Barbour" => "matthew@darkholme.net", "Discomrade" => ""];
public string $license = self::LICENSE_GPLV2;
public ExtensionCategory $category = ExtensionCategory::ADMIN;
public string $description = "Show performance tweak options. Read the documentation.";
public ?string $documentation =
"Many of these changes reduce the correctness of the software and increase admin workload for the sake of speed. You almost certainly don't want to set some of them, but if you do (e.g. you're trying to run a site with 10,000 concurrent users on a single server), it can be a huge help.
<br><br>
<ul>
<li><code>Don't auto-upgrade database</code>: Database schema upgrades are no longer automatic; you'll need to run <code>php index.php db-upgrade</code> from the CLI each time you update the code.</li>
<li><code>Cache event listeners</code>: Mapping from Events to Extensions is cached - you'll need to delete <code>data/cache/shm_event_listeners.php</code> after each code change, and after enabling or disabling any extensions.</li>
<li><code>Purge cookie on logout</code>: Clears the <code>user</code> cookie when a user logs out, to keep as few versions of content as possible.</li>
<li><code>List only recent comments</code>: Only comments from the past 24 hours show up in <code>/comment/list</code>.</li>
<li><code>Fast page limit</code>: We only show the first 500 pages of results for any query, except for the most simple (no tags, or one positive tag). Web crawlers are blocked from creating too many nonsense searches by limiting to 10 pages.</li>
<li><code>Anonymous search tag limit</code>: Anonymous users can only search for this many tags at once. To disable, set to 0.</li>
<li><code>Limit complex searches</code>: Only ever show the first 5,000 results for complex queries.</li>
<li><code>Fast page limit</code>: We only show the first 500 pages of results for any query, except for the most simple (no tags, or one positive tag) or users with the <code>BIG_SEARCH</code> permission. Web crawlers are blocked from creating too many nonsense searches by limiting to 10 pages. Consider enabling <code>Extra caching on first pages</code> as well.</li>
<li><code>Extra caching on first pages</code>: The first 10 pages in the <code>post/list</code> index get extra caching.</li>
<li><code>Limit images RSS</code>: RSS is limited to 10 pages for the image list.</li>
</ul>
";
}

55
ext/speed_hax/main.php Normal file
View file

@ -0,0 +1,55 @@
<?php
declare(strict_types=1);
namespace Shimmie2;
abstract class SpeedHaxConfig
{
public const NO_AUTO_DB_UPGRADE = "speed_hax_no_auto_db_upgrade";
public const CACHE_EVENT_LISTENERS = "speed_hax_cache_listeners";
public const CACHE_TAG_LISTS = "speed_hax_cache_tag_lists";
public const PURGE_COOKIE = "speed_hax_purge_cookie";
public const RECENT_COMMENTS = "speed_hax_recent_comments";
public const BIG_SEARCH = "speed_hax_big_search";
public const LIMIT_COMPLEX = "speed_hax_limit_complex";
public const FAST_PAGE_LIMIT = "speed_hax_fast_page_limit";
public const CACHE_FIRST_FEW = "speed_hax_cache_first_few";
public const RSS_LIMIT = "speed_hax_rss_limit";
}
class SpeedHax extends Extension
{
public function onInitExt(InitExtEvent $event): void
{
global $config;
$config->set_default_bool(SpeedHaxConfig::NO_AUTO_DB_UPGRADE, false);
$config->set_default_bool(SpeedHaxConfig::CACHE_EVENT_LISTENERS, false);
$config->set_default_bool(SpeedHaxConfig::CACHE_TAG_LISTS, false);
$config->set_default_bool(SpeedHaxConfig::PURGE_COOKIE, false);
$config->set_default_bool(SpeedHaxConfig::RECENT_COMMENTS, false);
$config->set_default_int(SpeedHaxConfig::BIG_SEARCH, 0);
$config->set_default_bool(SpeedHaxConfig::LIMIT_COMPLEX, false);
$config->set_default_bool(SpeedHaxConfig::FAST_PAGE_LIMIT, false);
$config->set_default_bool(SpeedHaxConfig::CACHE_FIRST_FEW, false);
$config->set_default_bool(SpeedHaxConfig::RSS_LIMIT, false);
}
public function onSetupBuilding(SetupBuildingEvent $event): void
{
$sb = $event->panel->create_new_block("Speed Hax");
$sb->start_table();
$sb->add_bool_option(SpeedHaxConfig::NO_AUTO_DB_UPGRADE, "Don't auto-upgrade database: ", false);
$sb->add_bool_option(SpeedHaxConfig::CACHE_EVENT_LISTENERS, "<br>Cache event listeners: ", false);
$sb->add_bool_option(SpeedHaxConfig::CACHE_TAG_LISTS, "<br>Cache tag lists: ", false);
$sb->add_bool_option(SpeedHaxConfig::PURGE_COOKIE, "<br>Purge cookie on logout: ", false);
$sb->add_bool_option(SpeedHaxConfig::RECENT_COMMENTS, "<br>List only recent comments: ", false);
$sb->add_int_option(SpeedHaxConfig::BIG_SEARCH, "<br>Anonymous search tag limit: ", false);
$sb->add_bool_option(SpeedHaxConfig::LIMIT_COMPLEX, "<br>Limit complex searches: ", false);
$sb->add_bool_option(SpeedHaxConfig::FAST_PAGE_LIMIT, "<br>Fast page limit: ", false);
$sb->add_bool_option(SpeedHaxConfig::CACHE_FIRST_FEW, "<br>Extra caching on first pages: ", false);
$sb->add_bool_option(SpeedHaxConfig::RSS_LIMIT, "<br>Limit images RSS: ", false);
$sb->end_table();
}
}

View file

@ -275,7 +275,7 @@ class TagList extends Extension
$html .= "&nbsp;<a style='font-size: {$size}em' href='$link'>$h_tag_no_underscores</a>&nbsp;\n";
}
if (SPEED_HAX) {
if (Extension::is_enabled(SpeedHaxInfo::KEY) && $config->get_bool(SpeedHaxConfig::CACHE_TAG_LISTS)) {
file_put_contents($cache_key, $html);
}
@ -349,7 +349,7 @@ class TagList extends Extension
$html .= "<a href='$link'>$h_tag</a>\n";
}
if (SPEED_HAX) {
if (Extension::is_enabled(SpeedHaxInfo::KEY) && $config->get_bool(SpeedHaxConfig::CACHE_TAG_LISTS)) {
file_put_contents($cache_key, $html);
}
@ -358,7 +358,7 @@ class TagList extends Extension
private function build_tag_popularity(int $tags_min): string
{
global $database;
global $config, $database;
// Make sure that the value of $tags_min is at least 1.
// Otherwise the database will complain if you try to do: LOG(0)
@ -396,7 +396,7 @@ class TagList extends Extension
$html .= "<a href='$link'>$h_tag&nbsp;($count)</a>\n";
}
if (SPEED_HAX) {
if (Extension::is_enabled(SpeedHaxInfo::KEY) && $config->get_bool(SpeedHaxConfig::CACHE_TAG_LISTS)) {
file_put_contents($cache_key, $html);
}

View file

@ -636,7 +636,7 @@ class UserPage extends Extension
{
global $page, $config;
$page->add_cookie("session", "", time() + 60 * 60 * 24 * $config->get_int('login_memory'), "/");
if (SPEED_HAX) {
if (Extension::is_enabled(SpeedHaxInfo::KEY) && $config->get_bool(SpeedHaxConfig::PURGE_COOKIE)) {
# to keep as few versions of content as possible,
# make cookies all-or-nothing
$page->add_cookie("user", "", time() + 60 * 60 * 24 * $config->get_int('login_memory'), "/");

View file

@ -71,7 +71,7 @@ try {
]
);
if (!SPEED_HAX) {
if (Extension::is_enabled(SpeedHaxInfo::KEY) && $config->get_bool(SpeedHaxConfig::NO_AUTO_DB_UPGRADE)) {
send_event(new DatabaseUpgradeEvent());
}
send_event(new InitExtEvent());

View file

@ -14,7 +14,6 @@ define("DATABASE_TIMEOUT", 10000);
define("CACHE_DSN", null);
define("DEBUG", false);
define("COOKIE_PREFIX", 'shm');
define("SPEED_HAX", false);
define("WH_SPLITS", 1);
define("VERSION", 'unit-tests');
define("TRACE_FILE", null);

View file

@ -8,7 +8,6 @@ parameters:
- ../themes
dynamicConstantNames:
- DEBUG
- SPEED_HAX
- TRUSTED_PROXIES
- TIMEZONE
- BASE_HREF