Skip to content

Cache Management ​

Flow ID: SY-07 | Module(s): job, helpers | Complexity: Low

Business Overview ​

Cache management ensures the application's file-based cache does not grow unbounded and can be selectively or fully cleared. Two complementary jobs handle this: one for on-demand or scheduled full/partial cache clearing, and another that monitors disk usage and auto-purges when a configurable size limit is exceeded. These jobs only act on file-based caching; Redis-backed deployments skip the size-monitoring job entirely.

Cache Tier Architecture ​

The application uses a 4-tier cache architecture:

┌─────────────────────────────────────────────────────────────────┐
│ L0: InMemory (per-request)                                      │
│   Static arrays within services. Lifetime = single PHP request. │
│   No serialization cost. Used for repeated lookups.             │
├─────────────────────────────────────────────────────────────────┤
│ L1: APCu / SHM (pod-local)                                     │
│   Shared memory on the same server. Fast, but not distributed.  │
│   Lost on PHP-FPM restart. Used for hot config and registry.    │
├─────────────────────────────────────────────────────────────────┤
│ L2: File / Redis (distributed)                                  │
│   Configurable via APP_CACHE_L2_ADAPTER (FileAdapter or Redis). │
│   Default TTL: 86400s (1 day). Survives restarts.               │
│   Search TTL: 43200s (12h). SEO TTL: 864000s (10 days).        │
├─────────────────────────────────────────────────────────────────┤
│ Session: Redis (7-day TTL)                                      │
│   Customer session data. Shared across pods in clustered envs.  │
└─────────────────────────────────────────────────────────────────┘

L2 TTL defaults:

CategoryTTLDescription
Default86,400s (1 day)Most cached data
Search43,200s (12 hours)Search results and facets
SEO864,000s (10 days)Meta tags, canonical URLs, sitemap data

PSCache wrapper: The Pscache library provides dependency tracking and language-aware cache keys (keys are suffixed with the active language abbreviation, e.g., /el/, /en/). This ensures multilingual content is cached separately per language.

Healthz endpoint: The application health check endpoint verifies both L1 and L2 cache health, returning degraded status if either tier is unavailable.

Development mode: When development mode is active, all cache expiration is set to TTL = -1 (disabled), effectively bypassing all caching layers.

Cache Invalidation Groups ​

10+ module invalidation groups are available via clearCache():

GroupModels/Keys Cleared
products13 product-related models (pricing, stock, attributes, variations, etc.)
searchsearch_model, lines_model
seometatags_model, seo_lib
cmscategories_model, subcontent_model
blogblog_category_model, blog_author_model, blog_tags_model, blog_model
slidersslideshow_group_model, sliders_model, slide_model
mapsmaps_model
promopromo_model
settingssettings, registry, registry_model, transporters_model, cookies_model
product_bundlesproduct_bundle_storage_model
cloudflareSpecial: calls clearCloudflareCache() (Cloudflare zone purge)
allFull purge via Pscache::delete_all()

Architecture ​

AdvClearSiteCache (job)        AdvClearCacheOnLimit (job)
       |                               |
       v                               v
JobClearCacheTrait             Check cache_l2_adapter
       |                         (FileAdapter only)
       v                               |
clearCache() helper                    v
  (pscache_helper)             du -s -k on cache path
       |                               |
       v                               v
clearPsCacheArray()            If over limit -> clearCache()
       |                               |
       v                               v
  Pscache                         Pscache
  delete_all() or                 delete_all()
  delete_group()

Key Components ​

ComponentPathRole
AdvClearSiteCacheecommercen/job/libraries/AdvClearSiteCache.phpJob: clears specific or all cache groups
AdvClearCacheOnLimitecommercen/job/libraries/AdvClearCacheOnLimit.phpJob: monitors file cache size, clears when over limit
JobClearCacheTraitecommercen/job/libraries/JobClearCacheTrait.phpShared trait providing clearCache() delegation
clearCache()ecommercen/helpers/pscache_helper.phpHelper: routes cache option to model-group clearing
clearPsCacheArray()ecommercen/helpers/pscache_helper.phpHelper: deletes all or specific cache groups via Pscache
clearCloudflareCache()ecommercen/helpers/pscache_helper.phpHelper: purges Cloudflare CDN cache via zone API
Pscacheapplication/libraries/Pscache.phpCache library wrapping PSR-6 CachePool
Client stubsapplication/modules/job/libraries/ClearSiteCache.php, ClearCacheOnLimit.phpEmpty extension points for client overrides

Code Flow ​

AdvClearSiteCache ​

  1. Entry: executeCommand(['cache' => $option]) where $option is an optional cache group name.
  2. Delegation: Calls $this->clearCache($option) via JobClearCacheTrait.
  3. Trait logic: If no option provided, defaults to 'all'.
  4. Helper dispatch: Calls global clearCache($option) from pscache_helper.php.
  5. Group resolution: A switch statement maps the option string to an array of model group names:
    • 'maps' -> ['maps_model']
    • 'cms' -> ['categories_model', 'subcontent_model']
    • 'blog' -> ['blog_category_model', 'blog_author_model', 'blog_tags_model', 'blog_model']
    • 'sliders' -> ['slideshow_group_model', 'sliders_model', 'slide_model']
    • 'promo' -> ['promo_model']
    • 'product_categories_vendors' -> ['product_category_model', 'vendors_model']
    • 'settings' -> ['settings', 'registry', 'registry_model', 'transporters_model', 'cookies_model']
    • 'seo' -> ['metatags_model', 'seo_lib']
    • 'products' -> 13 product-related models
    • 'search' -> ['search_model', 'lines_model']
    • 'product_bundles' -> ['product_bundle_storage_model']
    • 'cloudflare' -> Special path: calls clearCloudflareCache() directly (Cloudflare zone purge)
    • 'all' (default) -> Empty array, which triggers Pscache::delete_all()
  6. Cache deletion: clearPsCacheArray($models) calls either $pscache->delete_all() (when models is empty) or iterates and calls $pscache->delete_group(group: $model) for each model.

AdvClearCacheOnLimit ​

  1. Entry: executeCommand([]) -- no options.
  2. Adapter check: Reads cache_l2_adapter config. If not FileAdapter::class, logs info and returns (no-op for Redis).
  3. Size measurement: Executes du -s -k <cache_path> via shell exec() to get cache directory size in KB.
  4. Limit comparison: Compares measured size against getCacheSizeLimit() (config cache_l2_size_limit, in GB, converted to KB for comparison).
  5. Conditional clear: If size exceeds limit, calls $this->clearCache() (via trait -> full cache purge).
  6. Logging: Logs current cache size in GB and whether action was taken.

Data Model ​

No database tables are involved. Cache operates on the filesystem (or Redis, but the limit job only monitors files).

Config KeySourceDescription
cache_l2_adapterapplication/config/cache.phpAdapter FQCN (FileAdapter or RedisAdapter)
cache_l2_connectionapplication/config/cache.phpFile path or Redis connection string
cache_l2_size_limitapplication/config/cache.phpMax cache size in GB (default: 5)
cache_l2_default_expiresapplication/config/cache.phpDefault TTL in seconds (default: 86400)

Configuration ​

Environment Variables ​

VariableDefaultDescription
APP_CACHE_L2_ADAPTERFileAdapter::classCache adapter class
APP_CACHE_L2_CONNECTION../cache/Cache storage path
APP_CACHE_L2_SIZE_LIMIT5Size limit in GB (5 standard, 10 for dedicated)
APP_CACHE_L2_PREFIX''Cache key prefix

Job Options ​

JobOptionTypeRequiredDescription
AdvClearSiteCachecachestringNoCache group to clear (e.g., products, settings, all)
AdvClearCacheOnLimit(none)----No options; auto-detects adapter and path

Cache Group Names ​

Valid values for the cache option: maps, cms, blog, sliders, promo, product_categories_vendors, settings, seo, products, search, product_bundles, cloudflare, all.

Client Extension Points ​

  • Job override: Create ClearSiteCache or ClearCacheOnLimit in application/modules/job/libraries/ extending the Adv* base class to add custom cache groups or logic.
  • Cache group mapping: The clearCache() helper in pscache_helper.php can be overridden in client repos by defining the function before the helper loads.
  • Cloudflare integration: Clients with Cloudflare can use the cloudflare cache option to purge CDN cache via the Cloudflare library.

Business Rules ​

  1. File adapter only: AdvClearCacheOnLimit is a no-op when cache_l2_adapter is not FileAdapter. It silently logs and returns.
  2. Default is full purge: When no cache group is specified, AdvClearSiteCache clears all cached data.
  3. Size limit in GB: The cache_l2_size_limit config is in GB. Default is 5 GB globally; dedicated clients may use 10 GB.
  4. Shell dependency: AdvClearCacheOnLimit depends on the du command being available in the system PATH.
  5. Language-scoped path: Cache path includes the language abbreviation suffix (e.g., ../cache/el/).
  6. Development mode: In development, all cache expiration is set to -1 (disabled), so these jobs have limited effect.

Wiki Guide: Cache Guide -- cache adapter configuration and usage patterns