VOOZH about

URL: https://deepwiki.com/stefanak-michal/php-bolt-driver/3.4-caching-and-analytics

⇱ Caching and Analytics | stefanak-michal/php-bolt-driver | DeepWiki


Loading...
Last indexed: 14 February 2026 (a283bd)
Menu

Caching and Analytics

This document explains the caching infrastructure and analytics tracking system used by the Bolt PHP library. The caching system provides persistent storage for connection metadata and analytics data using a PSR-16 compliant file-based implementation. The analytics system collects anonymous usage metrics that help improve the library.

For server state tracking during protocol execution, see Server State Management. For persistent connection handling that relies on this cache system, see Persistent Connections with PStreamSocket.


Overview and Architecture

The library uses two primary subsystems for state persistence:

  1. FileCache - A PSR-16 Simple Cache implementation that stores serialized data in the temporary directory
  2. Analytics Tracking - Collects query and session counts, uploads them to Mixpanel for usage analysis

Both subsystems are accessed through the CacheProvider static accessor, which provides a single cache instance shared across all components.

System Components


Sources: src/helpers/CacheProvider.php1-29 src/helpers/FileCache.php1-219 src/Bolt.php1-262 src/protocol/AProtocol.php1-192


FileCache Implementation

The FileCache class implements the PSR-16 CacheInterface standard, providing a file-based caching mechanism that works without external dependencies.

Storage Structure

DirectoryPurposeContent
/tmp/php-bolt-filecache/Primary cache storageSerialized PHP values keyed by cache key
/tmp/php-bolt-filecache/.ttl/Time-to-live metadataUnix timestamps for key expiration

Core Operations

The cache validates keys against the pattern /^[\w\.]+$/i, allowing only alphanumeric characters, underscores, and dots. All values are serialized with allowed_classes => false for security.


Sources: src/helpers/FileCache.php68-108

Locking Mechanism

FileCache provides additional lock() and unlock() methods beyond the PSR-16 standard to enable thread-safe updates. This is critical for the analytics system where multiple PHP processes may update the same data concurrently.


The $handles property src/helpers/FileCache.php22 maintains an array of file handles for locked keys. The shutdown() method src/helpers/FileCache.php39-46 ensures all locks are released on script termination.

Sources: src/helpers/FileCache.php188-213

Time-to-Live (TTL) Support

TTL values can be specified as either:

  • Integer: Unix timestamp (absolute expiration time)
  • DateInterval: Relative time offset

The has() method src/helpers/FileCache.php172-186 automatically removes expired entries by comparing the stored timestamp against time().

Sources: src/helpers/FileCache.php90-99 src/helpers/FileCache.php172-186


CacheProvider Static Accessor

The CacheProvider class provides a static accessor pattern for the cache instance, ensuring all components share the same cache backend.

MethodPurpose
CacheProvider::get()Returns the current cache instance, lazy-initializing FileCache if needed
CacheProvider::set(CacheInterface $cache)Allows replacing the cache implementation with a custom PSR-16 adapter

This design allows applications to substitute FileCache with Redis, Memcached, or any other PSR-16 implementation by calling CacheProvider::set() early in their bootstrap process.

Sources: src/helpers/CacheProvider.php1-29


Persistent Connection Metadata Caching

The PStreamSocket connection class uses the cache to store protocol version information, enabling connection reuse across PHP requests without re-negotiating the protocol.

Connection Identifier Format


The identifier is computed in PStreamSocket::getIdentifier() src/connection/PStreamSocket.php60-65 and used as the cache key.

Protocol Version Storage Lifecycle


The 15-minute TTL src/Bolt.php139 balances connection reuse with the risk of stale metadata. When a cached version is found, the protocol is set to ServerState::INTERRUPTED src/Bolt.php174 and a RESET message verifies the connection is still valid src/Bolt.php176-180

Sources: src/Bolt.php138-143 src/Bolt.php159-185 src/connection/PStreamSocket.php60-65


Analytics Tracking System

The analytics system collects anonymous usage metrics to help the maintainers understand library adoption and usage patterns. All data is aggregated and anonymized before transmission.

Data Collection Points

EventTracked MetricLocation
Protocol message writequeries counter incrementAProtocol::write() increments $writeCalls src/protocol/AProtocol.php68-73
Protocol instance destructionAggregate daily countsAProtocol::__destruct() updates cache src/protocol/AProtocol.php170-191
Bolt instance creationUpload aggregated dataBolt::__construct() calls track() src/Bolt.php34

Analytics Data Structure


Keys are Unix timestamps for midnight UTC of each day (strtotime('today')). The queries count represents the total number of write operations (messages sent), while sessions represents the number of protocol instances destroyed.

Collection and Upload Flow


Sources: src/protocol/AProtocol.php170-191 src/Bolt.php40-114

Distinct ID Generation

The distinct ID anonymously identifies a unique installation without revealing user information:

sha1(php_uname() + disk_total_space('.') + filectime('/') + phpversion())

This combines system name, disk size, filesystem creation time, and PHP version to create a stable identifier that remains constant for a given environment but cannot be reverse-engineered to identify the user src/Bolt.php47

Mixpanel Event Format


The $insert_id uses the timestamp to ensure idempotency—Mixpanel will deduplicate events with the same ID, preventing double-counting if a request is retried src/Bolt.php54

Sources: src/Bolt.php49-71

Opting Out of Analytics

Set the BOLT_ANALYTICS_OPTOUT environment variable to any truthy value to disable analytics collection:


This is checked at two locations:

  1. Bolt::__construct() src/Bolt.php30 - Skips upload
  2. AProtocol::__destruct() src/protocol/AProtocol.php172 - Skips aggregation

When opted out, no data is collected, cached, or transmitted. For transparency, all collected analytics data is publicly viewable at the Mixpanel dashboard: https://eu.mixpanel.com/p/7ttVKqvjdqJtGCjLCFgdeC

Sources: src/Bolt.php30-35 src/protocol/AProtocol.php172-174 README.md288-292

Upload Mechanism Details

The upload uses cURL with the following configuration:

SettingValuePurpose
URLhttps://api-eu.mixpanel.com/importEU region endpoint
MethodPOSTBatch event import
TimeoutConnection timeout valueRespects user configuration
SSL VerificationDisabledAvoids certificate issues in varied environments
AuthorizationBasic MDJhYjRiOWE2YTM4MThmNWFlZDEzYjNiMmE5M2MxNzQ6Service account token

Only data from previous days ($time < strtotime('today')) is uploaded, ensuring today's in-progress counts remain in the cache for further aggregation src/Bolt.php51

Sources: src/Bolt.php78-114


Cache Directory Initialization

Both the cache and analytics systems require writable directories in the system temporary directory:

DirectoryCreated ByPurpose
/tmp/php-bolt-filecache/FileCache::__construct()General cache storage
/tmp/php-bolt-filecache/.ttl/FileCache::__construct()TTL metadata
/tmp/php-bolt-analytics/Bolt::__construct()Analytics working directory

All directories are created with mkdir(recursive: true) only if they don't exist and the parent directory is writable. If the temporary directory is not writable, both caching and analytics are silently disabled.

Sources: src/helpers/FileCache.php24-34 src/Bolt.php30-33


Thread Safety and Concurrency

The locking mechanism in FileCache ensures safe concurrent access in environments where multiple PHP processes may execute simultaneously (e.g., PHP-FPM, parallel test execution).

Locking Protocol


The locking is exclusive (LOCK_EX), meaning only one process can hold a lock at a time. Other processes attempting to lock the same key will block until the lock is released src/helpers/FileCache.php198

Analytics Update Pattern with Locking

The analytics update in AProtocol::__destruct() demonstrates proper locking usage:


The method_exists() checks allow compatibility with PSR-16 implementations that don't support locking src/protocol/AProtocol.php176

Sources: src/protocol/AProtocol.php176-190 src/Bolt.php100-112


Testing Considerations

The test infrastructure sets up the analytics directory if needed:


This ensures tests can run even when analytics is enabled, though most test environments set BOLT_ANALYTICS_OPTOUT=1 to avoid network calls during CI execution.

Sources: tests/protocol/ProtocolLayer.php103-107