VOOZH about

URL: https://deepwiki.com/hypervel/components/6.2-swoole-store-and-memory-management

⇱ Swoole Store and Memory Management | hypervel/components | DeepWiki


Loading...
Last indexed: 7 March 2026 (96fbab)
Menu

Swoole Store and Memory Management

Purpose and Scope

The Swoole Store provides high-performance in-memory caching using Swoole's shared memory table (Swoole\Table). This store leverages Swoole's native data structures to achieve coroutine-safe caching without the overhead of external cache servers. The store implements intelligent memory management with configurable eviction policies to prevent out-of-memory conditions.

This page covers the SwooleStore implementation, table configuration, memory limits, eviction strategies, and interval cache mechanisms. For general cache driver configuration, see Cache Manager and Drivers. For multi-tier caching strategies that layer Swoole Store with other stores, see Stack Store and Multi-Tier Caching.

Swoole Table Architecture

Table Structure and Initialization

The SwooleStore uses a SwooleTable instance (extending Swoole\Table) with a predefined column structure optimized for cache operations. The table is created and managed by SwooleTableManager, which is responsible for configuring the table schema and allocating shared memory.

Diagram: SwooleStore Component Relationships


Sources: src/cache/src/SwooleTable.php1-64 src/cache/src/SwooleTableManager.php1-63 src/cache/src/SwooleStore.php34-40

The table contains four columns defined in SwooleTableManager::createTable():

ColumnType (Swoole\Table constant)Purpose
valueTable::TYPE_STRINGSerialized cache value (size in bytes from config)
expirationTable::TYPE_FLOATUnix timestamp with microsecond precision when the item expires
last_used_atTable::TYPE_FLOATUnix timestamp with microsecond precision of last access (for LRU eviction)
used_countTable::TYPE_INTNumber of times the item has been accessed (for LFU eviction)

Sources: src/cache/src/SwooleTableManager.php21-33

The SwooleTable::column() method is called for each column during table initialization, and the table is stored in shared memory accessible across all Swoole worker processes and coroutines.

Sources: src/cache/src/SwooleTable.php23-28

Store Implementation

The SwooleStore class implements the Hypervel\Cache\Contracts\Store interface and provides cache operations on top of the Swoole Table.

Diagram: SwooleStore Method Flow


Sources: src/cache/src/SwooleStore.php14-372 src/cache/src/SwooleStore.php45-61 src/cache/src/SwooleStore.php85-97 src/cache/src/SwooleStore.php209-212

Access Tracking

Every get() operation automatically updates access tracking metadata used for eviction policies:

Sources: src/cache/src/SwooleStore.php261-275

The getRecord() method retrieves the record and updates:

  • last_used_at: Set to current microsecond timestamp
  • used_count: Incremented by 1

This tracking data is written back to the table on every access, enabling LRU and LFU eviction strategies without additional data structures.

Memory Management

Memory Limit Detection

The Swoole Store monitors memory usage to prevent table overflow. Memory pressure is detected using two metrics:


Sources: src/cache/src/SwooleStore.php288-296

The memoryLimitIsReached() method returns true when either:

  1. Conflict rate exceeds the threshold (indicating hash collisions)
  2. Memory usage exceeds the threshold (indicating table fullness)

The memory_limit_buffer configuration parameter (default 0.05) reserves a percentage of memory as buffer space. For example, with a 5% buffer, eviction begins when usage reaches 95%.

Eviction Process

When memory limits are reached during a put() operation, the store triggers an eviction sequence:


Sources: src/cache/src/SwooleStore.php249-256 src/cache/src/SwooleStore.php298-317

The eviction process has two phases:

  1. Flush stale records: Remove all expired items first
  2. Policy-based eviction: If still over limit, remove records according to the configured policy

Eviction Policies

The Swoole Store supports four eviction policies defined as class constants:

Policy ConstantValueBehavior
EVICTION_POLICY_LRU'lru'Remove least recently used items
EVICTION_POLICY_LFU'lfu'Remove least frequently used items
EVICTION_POLICY_TTL'ttl'Remove items expiring soonest
EVICTION_POLICY_NOEVICTION'noeviction'Do not evict (may cause writes to fail)

Sources: src/cache/src/SwooleStore.php16-22

Eviction Algorithm

All policy-based evictions use the same underlying mechanism implemented in handleRecordsEviction():

Diagram: handleRecordsEviction() Implementation


Sources: src/cache/src/SwooleStore.php334-354 src/cache/src/SwooleStore.php319-332 src/cache/src/LimitedMaxHeap.php9-30

The algorithm:

  1. Calculates how many records to evict based on eviction_proportion (e.g., 5% of table size)
  2. Creates a LimitedMaxHeap that maintains only the N smallest values
  3. Iterates all table records, inserting each record's policy-relevant column value
  4. Extracts all records from the heap and deletes them

The LimitedMaxHeap extends PHP's SplMaxHeap and automatically evicts larger values when the limit is reached. The insert() method (lines 15-29) compares incoming values against the current top of the heap and only inserts if the new value is smaller, maintaining exactly N smallest values efficiently in a single pass through the table.

Sources: src/cache/src/LimitedMaxHeap.php9-30 src/cache/src/LimitedMaxHeap.php15-29

Stale Record Flushing

Before policy-based eviction, the store removes all expired records:

Sources: src/cache/src/SwooleStore.php356-371

The flushStaleRecords() method:

  1. Gets the current timestamp
  2. Iterates all table records
  3. Collects keys where expiration < now
  4. Deletes all collected keys

This proactive cleanup ensures expired items don't count toward memory usage and may eliminate the need for policy-based eviction.

Interval Caches

The Swoole Store provides an interval cache mechanism for values that should be automatically refreshed on a schedule. This is useful for expensive computations or external API results that need periodic updates.

Interval Cache Structure


Sources: src/cache/src/SwooleStore.php161-176 src/cache/src/SwooleStore.php181-195 src/cache/src/SwooleStore.php45-61

Interval Cache Lifecycle

  1. Registration via interval(key, resolver, seconds):

    • Stores metadata at key 'interval-{key}' with a SerializableClosure of the resolver
    • Tracks the key in the $intervals array
    • Sets lastRefreshedAt to null initially
  2. First Access via get(key):

    • If the actual cache key doesn't exist or is expired
    • Checks if the key is in the intervals array
    • Executes the resolver immediately and returns the result
    • Does not store the result (relies on refresh cycle)
  3. Periodic Refresh via refreshIntervalCaches():

    • Iterates all registered interval keys
    • Checks if lastRefreshedAt + refreshInterval >= current time
    • Executes resolver and stores result with forever()
    • Updates lastRefreshedAt timestamp

Sources: src/cache/src/SwooleStore.php198-204

Interval caches are persisted using forever() which sets expiration to ONE_YEAR (31536000 seconds), and interval metadata keys are excluded from flush() operations.

Sources: src/cache/src/SwooleStore.php153-156 src/cache/src/SwooleStore.php217-228

Microsecond Precision

The Swoole Store uses microsecond-precision timestamps for all time-based operations to support sub-second cache expiration:

Sources: src/cache/src/SwooleStore.php280-283

The getCurrentTimestamp() method returns a float with 6 decimal places representing seconds:

  • Uses Carbon::now()->getPreciseTimestamp(6) which returns microseconds
  • Divides by 1,000,000 to convert to seconds with microsecond precision

This precision allows:

  • Cache items with sub-second TTLs (e.g., 0.5 seconds)
  • Accurate LRU tracking for high-frequency access patterns
  • Precise expiration detection avoiding premature or delayed eviction

Sources: tests/Cache/CacheSwooleStoreTest.php196-210

Periodic Cleanup Timers

The Swoole Store integrates with Swoole's timer system to perform periodic cleanup operations. This prevents memory exhaustion by proactively removing expired entries and enforcing eviction policies at regular intervals.

Diagram: Timer-Based Cleanup System


Sources: src/cache/src/Listeners/CreateTimer.php1-31 src/cache/src/SwooleStore.php249-256

The CreateTimer listener is triggered during the Hyperf framework's OnManagerStart event. For each configured Swoole cache store, it:

  1. Reads the eviction_interval configuration (default: 10000ms = 10 seconds)
  2. Creates a Swoole timer using Timer::tick() that repeats at the configured interval
  3. On each tick, retrieves the SwooleStore instance and calls evictRecords()
  4. The evictRecords() method performs both stale record flushing and policy-based eviction if memory limits are reached

This timer-based approach ensures memory management happens proactively in the background, rather than only during cache write operations. The timer runs in the Swoole manager process, operating independently of worker processes.

Sources: src/cache/src/Listeners/CreateTimer.php22-29

Configuration

Store Configuration

The Swoole Store is configured in the cache configuration file under cache.stores:

















































ParameterTypeDefaultDescription
driverstring-Must be 'swoole'
tablestring-Reference to Swoole table configuration name
memory_limit_bufferfloat0.05Percentage of memory to reserve as buffer (5% = start evicting at 95% full)
eviction_policystring'lru'Eviction strategy: 'lru', 'lfu', 'ttl', or 'noeviction'
eviction_proportionfloat0.05Percentage of records to remove per eviction cycle (5% = remove 5% of table size)
eviction_intervalint10000Interval in milliseconds for periodic cleanup timer

Sources: src/cache/src/CacheManager.php250-261 src/cache/src/Listeners/CreateTimer.php23

Table Configuration

Swoole tables are configured separately under cache.swoole_tables:































ParameterTypeDefaultDescription
rowsint1024Maximum number of rows (cache entries)
bytesint10240Maximum size in bytes for the value column
conflict_proportionfloat0.2Hash conflict proportion (higher = more memory, fewer conflicts)

Sources: src/cache/src/SwooleTableManager.php40-53

The rows parameter determines the table size. The actual memory allocated by Swoole will be:

  • rows * (1 + conflict_proportion) for hash table management
  • Plus column storage overhead

Value Size Validation

The SwooleTable class validates that stored values don't exceed the configured bytes limit:

Sources: src/cache/src/SwooleTable.php33-63

If a value exceeds the column size, a ValueTooLargeForColumnException is thrown with a detailed message showing:

  • First 20 characters of the value
  • Column name
  • Configured size limit
  • Actual size

Integration with CacheManager

The CacheManager creates Swoole Store instances via the createSwooleDriver() method:

Sources: src/cache/src/CacheManager.php250-261

The creation process:

  1. Retrieves the SwooleTableManager from the container
  2. Gets the configured table by name via SwooleTableManager::get()
  3. Instantiates SwooleStore with the table and configuration parameters
  4. Wraps the store in a Repository for the public cache API

This integration allows the Swoole Store to be used like any other cache driver through the unified cache facade.