rollerworks/cache-bundle
Rollerworks CacheBundle is a Symfony bundle that adds caching services and configuration to your application, helping you wire up cache pools and HTTP caching with less boilerplate. A lightweight integration for projects already using the Rollerworks component stack.
Read this first: this bundle is archived and its last release was 2015-12-05. It targets Symfony 2.x. Nothing here changes the fact that you should not pick it for new work — the guidance below is for maintaining a legacy app that already depends on it, or for judging what a migration would cost.
Install (legacy Symfony 2.x only)
composer require rollerworks/cache-bundle
Composer will print an abandonment warning. Pin the constraint ("rollerworks/cache-bundle": "~1.0") so a future resolver change can't pull an unexpected build, and commit composer.lock.
Register the bundle
// app/AppKernel.php
$bundles = array(
// ...
new Rollerworks\Bundle\CacheBundle\RollerworksCacheBundle(),
);
Confirm the exact class name from vendor/rollerworks/cache-bundle/RollerworksCacheBundle.php — the repository README is thin, so vendor source is the source of truth.
Configure a driver
# app/config/config.yml
rollerworks_cache:
driver: filesystem
options:
directory: "%kernel.cache_dir%/rollerworks"
lifetime: 3600
Where to look first (in this order)
DependencyInjection/Configuration.php — the canonical, complete list of option keys. Every blog snippet you find for this bundle is older than this file.Resources/config/services.xml (or .yml) — the service IDs you will actually inject, plus the container parameter the driver is stored in.vendor/rollerworks/cache/ — the component's CacheInterface. Whatever methods it exposes (get/set/contains/remove, or an item-based API) is what you'll write against; the bundle only wires it.First use case: cache one expensive read. Inject the cache service into the service that performs the query, check, miss, populate.
if ($this->cache->contains($key)) {
return $this->cache->get($key);
}
$value = $this->repository->expensiveQuery();
$this->cache->set($key, $value, 3600);
return $value;
Inject the service, not the container. Wire it into your own services in services.yml:
services:
app.report_generator:
class: AppBundle\Service\ReportGenerator
arguments: ["@rollerworks_cache.cache", 3600]
If the service ID differs in your version, take it from Resources/config/services.xml — do not guess.
Decorate repositories rather than sprinkling cache calls. The single most maintainable pattern with this bundle is a caching decorator behind the same interface, so callers stay cache-unaware:
class CachedProductRepository implements ProductRepositoryInterface
{
public function __construct(
private ProductRepositoryInterface $inner,
private CacheInterface $cache,
private int $ttl = 3600
) {}
public function find(int $id): ?Product
{
$key = sprintf('product.v2.%d', $id);
if ($this->cache->contains($key)) {
return $this->cache->get($key);
}
$product = $this->inner->find($id);
$this->cache->set($key, $product, $this->ttl);
return $product;
}
}
Namespacing discipline. Prefix every key with <domain>.<schema-version>.. The version segment is what lets you invalidate everything after a serialization change without hunting down keys.
Version-counter invalidation. This bundle predates tag support. For "clear all products" semantics, keep a counter key and fold it into the cache key:
$version = $this->cache->get('product.version', 1);
$key = sprintf('product.%d.%d', $version, $id);
// bust: $this->cache->set('product.version', $version + 1);
Environment split. Use the array/in-memory driver in config_test.yml so tests never see stale state and cache:clear isn't needed between runs. Production gets filesystem or APCu.
Warmup command. Add a console command that populates the hot keys after deploy. There is no built-in warmer, and this bundle's cache lives under kernel.cache_dir in the default config — meaning cache:clear on deploy guarantees a cold start.
Wrap it now. Before touching feature code, put your own App\Cache\CacheInterface in front of the bundle's API. Every call site then depends on your interface, and the eventual symfony/cache migration becomes one adapter class instead of a grep-and-replace across the codebase.
It is a dead end, and plan around that. Archived, one star, zero dependents, no Symfony 3/4/5 support (Symfony 3 removed APIs this bundle's DI layer relies on). There will be no security fixes. Treat any hour spent on it as sunk cost toward migration, not investment.
No PSR-6 or PSR-16. This is the decisive technical fact for an assessment. You cannot swap in symfony/cache, cache/adapter, or any modern pool behind this interface. Everything you write is bespoke, which is exactly why the adapter-wrapper advice above matters.
Values must be serializable. Drivers that persist (filesystem, APCu) serialise with serialize(). Closures, resources, PDO handles, and entities with lazy proxies attached will blow up on read — often months later, on the first cache hit rather than on write. Cache scalars and plain arrays, or DTOs that are explicitly JsonSerializable/hydrated by hand rather than Doctrine entities.
No stampede protection. There's no locking, no probabilistic early expiration. A hot key expiring under load sends the full request storm into your database. Add jitter to your TTLs (3600 + random_int(-300, 300)) or guard the miss path with a lock.
The driver is fixed at container compile time. You cannot choose a driver per request or per tenant through configuration. If you need that, register a factory service that receives raw connection parameters and constructs the component's cache class yourself — the bundle's config is not a runtime registry.
cache:clear wipes it. With the default directory under %kernel.cache_dir%, every deploy is a cold cache. This is safe but expensive; either move the directory to %kernel.root_dir%/var/cache-data and clear it yourself, or accept the warmup command as a mandatory deploy step.
Debugging is manual. No web profiler panel, no data collector, no hit/miss metrics. When something looks wrong, inspect the filesystem directory directly (ls the key hash files, unserialize one) or temporarily decorate the cache service with a logging decorator that records key, hit/miss, and TTL. Add that decorator in config_dev.yml — it pays for itself within a day.
Extension point: decorator, not subclass. If you need behaviour the bundle doesn't offer (logging, metrics, key prefixing), decorate rollerworks_cache.cache in your own bundle's services.yml with decorates:. Reaching into the component's driver classes is more fragile than wrapping the interface the bundle exposes.
Migration target. When you move: symfony/cache, cache.app and cache.system pools, CacheItem semantics, and TagAwareAdapter for the invalidation pattern you hand-rolled above. The mapping is mechanical if — and only if — you did the adapter-wrapper step first; otherwise budget for a codebase-wide sweep.
How can I help you explore Laravel packages today?