-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStarVersionStore.php
More file actions
144 lines (128 loc) · 4.96 KB
/
StarVersionStore.php
File metadata and controls
144 lines (128 loc) · 4.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
<?php
declare(strict_types=1);
namespace StarCache;
/**
* StarVersionStore — Version-based cache invalidation
*
* Maintains monotonically-increasing integer version counters for named groups.
* When a version is bumped the counter increments, which causes all subsequent
* cache-key lookups (which embed the version) to miss automatically.
* Stale entries expire naturally on their own TTL — no flush required.
*
* This avoids the thundering-herd problem caused by global cache flushes and
* is consistent with how WordPress VIP handles cache invalidation without
* relying on `wp_cache_flush()`.
*
* Built-in groups
* ---------------
* GROUP_PAGES — full-page cache entries (bumped on save_post / status change)
* GROUP_QUERIES — WP_Query results (bumped on clean_post_cache)
* GROUP_OBJECTS — arbitrary object cache (bumped for fragment / data cache)
*
* WP-CLI integration
* ------------------
* wp starcache flush → bumps all groups (NOT a global flush)
* wp starcache status → shows backend + context
*
* @package StarCache
* @author MaximillianGroup (Max Barrett) <maximilliangroup@gmail.com>
* @version 2.1.1
* @license Apache 2.0
*/
class StarVersionStore
{
// -------------------------------------------------------------------------
// Group name constants
// -------------------------------------------------------------------------
/** Full-page cache version group. */
public const GROUP_PAGES = 'pages';
/** WP_Query / SQL result cache version group. */
public const GROUP_QUERIES = 'queries';
/** Arbitrary object / fragment cache version group. */
public const GROUP_OBJECTS = 'objects';
// -------------------------------------------------------------------------
// Internal
// -------------------------------------------------------------------------
private const KEY_PREFIX = 'sc_ver_';
private const CACHE_GROUP = 'starcache_version';
private const INITIAL_VER = 1;
// -------------------------------------------------------------------------
// Public API
// -------------------------------------------------------------------------
/**
* Return the current version number for a named group.
*
* @param string $group Logical group name (use GROUP_* constants).
* @return int Version number (≥ 1).
*/
public static function get(string $group): int
{
$key = self::buildKey($group);
$version = StarCacheAdapter::get($key, self::CACHE_GROUP);
return ($version !== false && is_int($version)) ? $version : self::INITIAL_VER;
}
/**
* Increment the version for a named group by 1.
*
* All cache entries whose keys embedded the previous version number are
* now effectively unreachable and will expire naturally.
*
* @param string $group Logical group name.
* @return int The new (incremented) version number.
*/
public static function bump(string $group): int
{
$key = self::buildKey($group);
$newVersion = self::atomicBump($key);
do_action('starcache_version_bumped', $group, $newVersion);
return $newVersion;
}
/**
* Reset a group's version back to the initial value (1).
*
* Use only for testing or after a full cache flush on deploy.
*
* @param string $group
*/
public static function reset(string $group): void
{
StarCacheAdapter::set(self::buildKey($group), self::INITIAL_VER, 0, self::CACHE_GROUP);
}
/**
* Bump all built-in groups at once.
* Called by WP-CLI `wp starcache flush` — NOT a global cache flush.
*/
public static function bumpAll(): void
{
self::bump(self::GROUP_PAGES);
self::bump(self::GROUP_QUERIES);
self::bump(self::GROUP_OBJECTS);
}
// -------------------------------------------------------------------------
// Internal helpers
// -------------------------------------------------------------------------
/**
* Build the raw (non-hashed) storage key for a version counter.
*
* Keys are scoped to the current blog ID for multisite isolation.
*/
private static function buildKey(string $group): string
{
$blogId = function_exists('get_current_blog_id') ? get_current_blog_id() : 1;
return self::KEY_PREFIX . $blogId . '_' . hash('sha256', $group);
}
/**
* Bump a version key using the adapter storage format.
*
* Version keys may already exist as adapter-serialized values, so backend-
* specific raw counter APIs (`incr`/`increment`) are not safe here. Instead,
* store a fresh high-resolution timestamp through the adapter so reads and
* writes always use the same format.
*/
private static function atomicBump(string $key): int
{
$newVersion = hrtime(true);
StarCacheAdapter::set($key, $newVersion, 0, self::CACHE_GROUP);
return $newVersion;
}
}