Özel sürüm önizlemesiGerçek ödeme alınmazSürüm ayrıntıları ↗

EN · ÖZGÜN DEPO BELGESİ

Bağımsız Free motoru

Özgün İngilizce metin. Komutlar ve kanıtlar, belgede belirtilen revizyona ve ortama aittir.

product/free-core/cache-core-free/README.md

Bu sayfada

Original standalone Free cache engine

This bounded implementation is independently authored in this task against public WordPress cache API contracts and Redis protocol documentation. It is not a clean-room claim: the worker previously inspected other implementations for earlier review tasks. No code was copied from proprietary Object Cache Pro or the GPL Redis Object Cache dependency. GPL-2.0-or-later applies only to newly authored files in this component; the surrounding repository’s upstream notices remain unchanged.

Public references inspected on 2026-10-02:

No source/asset bundling from those projects is needed; the included GPL-2 text is standard license material. Maintainer/brand identity and WordPress.org review remain publication gates. There has been no public submission or deployment.

Explicit configuration and lifecycle

define('CACHE_CORE_FREE_CONFIG', [
    'host' => '127.0.0.1', 'port' => 6379, 'database' => 0,
    'prefix' => 'operator-unique-installation-identifier',
    // Optional: 'recovery_dir' => '/durable/shared/php-uid-owned/cache-recovery',
    'timeout' => 0.5, 'read_timeout' => 0.5,
    // 'password' => 'operator-secret', // or ['acl-user', 'operator-secret']
]);

Baseline: WordPress 6.5+, PHP 8.0+, PhpRedis, Redis 6.2+, single server, plain TCP. Unique nonempty prefix is REQUIRED for persistence. Missing prefix means local-only caching and no Redis writes. Different installations must use distinct prefixes in a shared Redis database. Configuration errors/connectivity fail softly without showing credential-bearing exceptions.

Activation does not enable persistence. The admin Tools/network Settings form uses capability plus nonce checks for enable/update/disable. The fixture/integration API is CacheCoreFree\manage_dropin('enable'|'update'|'disable') after loading plugin or lifecycle.php. It refuses foreign files and symlinks; enable atomically publishes without overwriting, own update uses same-directory atomic replacement. Actions serialize using a local lock. Concurrent external filesystem actors do not honor that lock and require operator coordination. The installed owned drop-in embeds only the original engine plus wrappers, so plugin-folder absence cannot break its runtime dependency. Source template should not be manually copied as an installed drop-in. Explicit update installs a new snapshot; no remote code updater exists.

Semantics and limits

Scalar/array/object values use a format-marked PHP serialization envelope, so false and null remain distinct found values. Redis is trusted operator infrastructure; as with PHP object caching generally, do not allow untrusted parties to inject serialized PHP objects into this namespace. Top-level object clone behavior follows WordPress; deep mutable references are not independently cloned.

Persistent reads obtain value and TTL atomically; local expiry is conservative. Bulk operations return keyed caller order and currently loop over single operations, not an optimized pipeline or all-or-nothing batch. Add/replace use SET NX/XX.

Numeric operations WATCH the value and namespace generation, read the existing PHP value, apply PHP is_numeric conversion (otherwise zero), cast only offset to integer, clamp negative results to zero, then MULTI/EXEC SET XX KEEPTTL. Thus Redis preserves its exact expiration without PHP wall-clock arithmetic or Lua double conversion. Eight conflicted attempts return false and invalidate that local value, without claiming mutation success or disabling a healthy backend. Redis errors clear previous persistent runtime entries and disable the backend for the entire request. Offline request-local writes are never replayed automatically.

Recovery uses a durable per-request ticket and shared request lease in a local filesystem lock domain. The ticket exists before Redis connects. Failed/crashed requests retain their ticket; a pending marker also stops overlapping requests from trusting persistent runtime/Redis data. A subsequent healthy request must obtain an exclusive lease, wait until earlier SQL writers have finished, and rotate this namespace before it can resume persistent reads/writes. Recovery never replays offline writes. Every connection attempt holds only a shared lease, including initial Redis outages. Recovery upgrades to exclusive only under the state lock and restores shared even on failed upgrades or failed invalidation. A live earlier writer keeps recovery request-local with recovery_waiting_for_requests. A new request arriving during actual exclusive invalidation waits at most 1000 retries with 1ms pauses; exhaustion refuses bootstrap with recovery_lease_busy before any unrecorded SQL writer.

recovery_dir defaults to WP_CONTENT_DIR/.cache-core-free-recovery; an optional absolute configured path must survive requests and use a coherent flock-capable filesystem. Each prefix has a hashed subdirectory, fixed lock inodes, atomic state and private 0600 tickets/0700 directories. Web and CLI MUST run under the same PHP UID, or operators must provision a compatible path/ownership policy. All nodes sharing a Redis namespace MUST share this same filesystem/lock domain; independent node-local paths are unsupported. Shared filesystem/multi-node operation is not validated. Losing initial state forces namespace invalidation. Missing/unwritable initial recovery setup or ticket fails bootstrap with an actionable error: silently allowing unrecorded SQL writes would make later Redis reuse unsafe. Ordinary Redis outages after the ticket exists remain fail-soft. This availability tradeoff is intentional. No ticket or marker contains credentials or cached values.

State-lock contention retries at most 20 times with 1ms pauses. Every persistent operation checks the marker and at most 1000 ticket records (1010 directory entries); excess state disables persistence with a diagnostic. Healthy teardown removes only its own ticket, failed teardown leaves it behind. Filesystem repair, restoring a backup of recovery state, namespace/path migration, and power-loss durability require operator coordination and namespace invalidation; process-crash ticket recovery is implemented, machine power-loss guarantees are not established. WordPress database changes made outside this plugin’s cache requests remain outside this recovery contract. Existing in-flight operations still have ordinary cache invalidation races around generation switches.

wp_cache_flush() rotates this installation’s namespace generation, leaving other prefixes untouched, then runs a bounded scoped SCAN/UNLINK cleanup of valid old 32-hex-generation/64-hex-value keys under only its hashed installation prefix. Each deletion batch WATCHes the generation so a concurrent rotation cannot let this cleanup delete another flush’s current data. Maximum per flush: 10 SCAN calls, 1000 visited keys and 100-key deletion batches. Metadata, malformed/unrecognized keys, other prefixes and the observed current generation are never selected. Status reports scoped_cleanup: pending when capped or interrupted by another rotation, and pending after backend failure on errors. Logical flush does not guarantee complete physical purge or memory reclamation: remaining keys (including expire=0) can persist until another scoped cleanup or eviction, and concurrent old-generation writers can add keys after the scan. Capacity remains a material release limitation even when a bounded scan completes. Offline flush returns false because remote invalidation could not happen. Group flush support is false and the wrapper also returns false, avoiding WordPress’s possible global-flush polyfill.

No Sentinel/Cluster/Relay/TLS or performance superiority claims. Runtime absence of PhpRedis falls back to request-local caching. Broader PHP/Redis/WordPress versions, network partitions, production concurrency and unrelated plugin workloads need separate evidence before production release.

Validation

Focused original fixture tests outside the distributable folder:

php product/free-core/tests/faults.php
php product/free-core/tests/lifecycle.php

These stubs prove bounded failure/local behavior and file ownership behavior; real WordPress multisite, Redis CAS concurrency, TTL and lifecycle tests belong to the integration owner’s exact-code/version report. No passing evidence should be inferred merely from the presence of the source or this README.

Actual Cloud evidence

The original runtime passed 66 public-cache assertions, 16 cross-process scope/ flush assertions and 17 actual Redis recovery/TTL assertions on WordPress 6.8.3, PHP 8.3.28, PhpRedis 6.1.0 and Redis 7.4.2. Four concurrent workers persisted all 78 successful increments; two of 80 attempts explicitly returned false at the CAS retry limit. Actual service pause/unpause confirmed stale runtime removal, fresh request-local fallback and recovery after operator namespace invalidation (before the automatic recovery lease change), without replaying offline writes. An earlier Docker stop/DNS case exceeded the 20-second harness budget; socket cleanup was corrected, but DNS latency is not established as bounded by the Redis connect timeout.

HTTP lifecycle tests use real forms/permissions/nonces, not browser visual QA. Publishing an absent drop-in now invalidates the configured namespace before installation to prevent stale cache and network-plugin metadata after re-enable. Failed invalidation refuses configured enable. The explicit local-only path with missing prefix remains allowed. These are private fixture results; other runtime versions and broader production workloads remain unvalidated.

Automatic lease/ticket recovery adds focused local tests; actual Redis retained-state and delayed-writer evidence must be reported for the final exact installed snapshot.