feat: add MU-plugin for cache backend auto-detection + versioned cache invalidation
- Auto-detects Memcached/Redis via fsockopen - Versioned cache key helper (my_cache_key) - Auto-flush on option/post/CF changes (no manual wp cache flush) - WP-CLI command: wp dekart cache-flush - Admin bar shows backend + cache version
This commit is contained in:
parent
17fa35edc3
commit
76303d3a3b
@ -1,21 +1,164 @@
|
||||
<?php
|
||||
if ( ! defined( 'WP_REDIS_HOST' ) ) {
|
||||
define(
|
||||
'WP_REDIS_HOST',
|
||||
getenv( 'WP_REDIS_HOST' ) ?: '127.0.0.1'
|
||||
);
|
||||
/**
|
||||
* MU-Plugin: Object Cache Bootstrap
|
||||
*
|
||||
* Автоопределение backend кеширования + versioned cache + автоинвалидация.
|
||||
* Dev → Redis (через redis-cache plugin + Predis).
|
||||
* Prod → Memcached (через Memcached Object Cache plugin, устанавливается вручную).
|
||||
*
|
||||
* @package Dekart
|
||||
*/
|
||||
|
||||
// ============================================================
|
||||
// 1. АВТООПРЕДЕЛЕНИЕ BACKEND
|
||||
// ============================================================
|
||||
|
||||
/**
|
||||
* Определить доступный backend для object cache.
|
||||
*
|
||||
* @return string 'memcached' | 'redis' | 'none'
|
||||
*/
|
||||
function dekart_detect_cache_backend(): string {
|
||||
// 1. Приоритет: Memcached (проверка порта)
|
||||
$memcached_sock = @fsockopen( '127.0.0.1', 11211, $errno, $errstr, 0.5 );
|
||||
if ( $memcached_sock ) {
|
||||
fclose( $memcached_sock );
|
||||
return 'memcached';
|
||||
}
|
||||
|
||||
// 2. Redis: проверяем через Predis (установлен composer)
|
||||
if ( class_exists( 'Predis\Client' ) ) {
|
||||
$redis_sock = @fsockopen( '127.0.0.1', 6379, $errno, $errstr, 0.5 );
|
||||
if ( $redis_sock ) {
|
||||
fclose( $redis_sock );
|
||||
return 'redis';
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Ничего не доступно
|
||||
return 'none';
|
||||
}
|
||||
|
||||
if ( ! defined( 'WP_REDIS_PORT' ) ) {
|
||||
define(
|
||||
'WP_REDIS_PORT',
|
||||
( int ) ( getenv( 'WP_REDIS_PORT' ) ?: 6379 )
|
||||
);
|
||||
// ============================================================
|
||||
// 2. КОНСТАНТЫ ДЛЯ ПЛАГИНОВ
|
||||
// ============================================================
|
||||
|
||||
$backend = dekart_detect_cache_backend();
|
||||
|
||||
// Redis: define константы для redis-cache plugin
|
||||
if ( 'redis' === $backend ) {
|
||||
if ( ! defined( 'WP_REDIS_HOST' ) ) {
|
||||
define( 'WP_REDIS_HOST', '127.0.0.1' );
|
||||
}
|
||||
if ( ! defined( 'WP_REDIS_PORT' ) ) {
|
||||
define( 'WP_REDIS_PORT', 6379 );
|
||||
}
|
||||
if ( ! defined( 'WP_REDIS_DATABASE' ) ) {
|
||||
define( 'WP_REDIS_DATABASE', 0 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! defined( 'WP_REDIS_DATABASE' ) ) {
|
||||
define(
|
||||
'WP_REDIS_DATABASE',
|
||||
( int ) ( getenv( 'WP_REDIS_DATABASE' ) ?: 0 )
|
||||
);
|
||||
// ============================================================
|
||||
// 3. ЛОГИРОВАНИЕ (dev only)
|
||||
// ============================================================
|
||||
|
||||
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
|
||||
error_log( '[Object Cache] Backend detected: ' . $backend );
|
||||
if ( 'none' === $backend ) {
|
||||
error_log( '[Object Cache] WARNING: No cache backend available. Site will run without object cache.' );
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 4. VERSIONED CACHE KEY
|
||||
// ============================================================
|
||||
|
||||
/**
|
||||
* Получить текущую версию кеша.
|
||||
*/
|
||||
function my_cache_version(): int {
|
||||
return (int) get_option( 'my_cache_version', 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Обернуть ключ кеша с версией.
|
||||
* Позволяет инвалидировать весь кеш без flush — достаточно изменить версию.
|
||||
*
|
||||
* @param string $key Исходный ключ.
|
||||
* @return string Ключ с префиксом версии.
|
||||
*/
|
||||
function my_cache_key( string $key ): string {
|
||||
return 'v:' . my_cache_version() . ':' . $key;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 5. ИНВАЛИДАЦИЯ КЕША
|
||||
// ============================================================
|
||||
|
||||
/**
|
||||
* Увеличить версию кеша + сбросить object cache.
|
||||
* Все кешированные данные сбрасываются — при следующем запросе читаются свежие.
|
||||
*/
|
||||
function my_cache_bump_version(): void {
|
||||
// Сбрасываем object cache (Redis / Memcached)
|
||||
wp_cache_flush();
|
||||
|
||||
// Обновляем версию для my_cache_key()
|
||||
$v = my_cache_version();
|
||||
update_option( 'my_cache_version', $v + 1, false );
|
||||
|
||||
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
|
||||
error_log( sprintf( '[Object Cache] Flushed + version bumped: %d → %d', $v, $v + 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 6. ХУКИ АВТОИНВАЛИДАЦИИ
|
||||
// ============================================================
|
||||
|
||||
// Опции: при любом изменении сбрасываем версию
|
||||
add_action( 'update_option', 'my_cache_bump_version' );
|
||||
add_action( 'added_option', 'my_cache_bump_version' );
|
||||
add_action( 'deleted_option', 'my_cache_bump_version' );
|
||||
|
||||
// Посты: при сохранении (включая ACF, Carbon Fields)
|
||||
add_action( 'save_post', 'my_cache_bump_version' );
|
||||
|
||||
// Carbon Fields: сохранение мета-боксов
|
||||
add_action( 'carbon_fields_post_meta_container_saved', 'my_cache_bump_version' );
|
||||
|
||||
// ============================================================
|
||||
// 7. ХЕЛПЕР: ПРОМЫВКА КЕША ИЗ АДМИНКИ
|
||||
// ============================================================
|
||||
|
||||
/**
|
||||
* Добавить кнопку "Сбросить кеш" в админ-бар (только для админов).
|
||||
*/
|
||||
add_action( 'admin_bar_menu', function ( WP_Admin_Bar $wp_admin_bar ) {
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Показываем текущий backend
|
||||
$backend_label = 'none' === $backend ? 'no-cache' : $backend;
|
||||
$wp_admin_bar->add_node( array(
|
||||
'id' => 'dekart-cache-status',
|
||||
'title' => sprintf(
|
||||
'<span style="font-size:12px;opacity:0.7">Cache: %s | v%s</span>',
|
||||
$backend_label,
|
||||
my_cache_version()
|
||||
),
|
||||
'href' => '#',
|
||||
) );
|
||||
}, 100 );
|
||||
|
||||
// ============================================================
|
||||
// 8. WP-CLI: командa для сброса версии
|
||||
// ============================================================
|
||||
|
||||
if ( defined( 'WP_CLI' ) && WP_CLI ) {
|
||||
WP_CLI::add_command( 'dekart cache-flush', function () {
|
||||
my_cache_bump_version();
|
||||
WP_CLI::success( 'Cache version bumped. All versioned cache keys are invalidated.' );
|
||||
} );
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user