vatvit/freshen-symfony
Composer 安装命令:
composer require vatvit/freshen-symfony
包简介
Symfony bundle for Freshen — drop-in stale-while-revalidate cache with stampede prevention.
README 文档
README
⚠️ Read-only mirror. This repository is the Packagist publish mirror of
packages/symfonyin the Freshen monorepo. Source, issues, and pull requests live there — please don't open them here. Install withcomposer require vatvit/freshen-symfony.
Freshen — Symfony bundle
Security — tracked by the Packagist security advisory database; run
composer auditto check your install. Report privately via GitHub Security Advisories; policy in SECURITY.md.
vatvit/freshen-symfony is the drop-in Symfony bundle for
Freshen, the stale-while-revalidate cache with
stampede prevention. It wires the manual pool/loader/listener setup from the core
README into declarative config: composer require + a little YAML gives you one autowired,
per-dataset Freshen\Cache per data structure, injected by name, with async invalidation
already registered.
Install
composer require vatvit/freshen-symfony
Register the bundle (Symfony Flex does this automatically):
// config/bundles.php return [ // ... Freshen\Bridge\Symfony\FreshenBundle::class => ['all' => true], ];
Configure
Freshen\Cache is per-dataset — each cache binds one loader + TTL — so you declare
named caches. Each references a loader service (yours, implementing
Freshen\Interface\LoaderInterface) and a \Redis client service.
A Freshen cache is one dataset, so you define one entry per data structure (top sellers, prices, …) — a real app has several:
# config/packages/freshen.yaml freshen: connection: Redis # shared \Redis client service id (optional if each cache sets its own) caches: top_sellers: loader: App\Cache\TopSellersLoader # required — Freshen\Interface\LoaderInterface service hard_ttl: 3600 # required, seconds (>= 1) precompute: 60 # default 0 — soft window before hard TTL jitter: 15 # default 15 (percent) fail_open: true # default true # connection: Redis # optional per-cache override # metrics: App\Cache\Metrics # optional — Freshen\Interface\MetricsInterface service prices: # a second dataset — its own loader + TTLs loader: App\Cache\PricesLoader hard_ttl: 600 precompute: 30
The connection value is a service id for a connected \Redis client. Bring your
own, e.g.:
# config/services.yaml services: Redis: class: Redis calls: - connect: ['%env(REDIS_HOST)%', '%env(int:REDIS_PORT)%']
Use
Inject each cache by name with named-argument autowiring — the argument name is the
camel-cased cache name plus Cache. This is how you reference a dataset whether you have
one cache or many (there is no bare Freshen\Cache "default" — with several datasets it
would be ambiguous, and it would silently break the day you add the second one):
public function __construct( private \Freshen\Cache $topSellersCache, // freshen.caches.top_sellers private \Freshen\Cache $pricesCache, // freshen.caches.prices ) {} $key = new \Freshen\Key('product', 'detail', $id); $result = $this->topSellersCache->get($key); $result->value(); // fresh or stale-while-revalidate value $this->topSellersCache->invalidate($key); // async by default — see below
Async invalidation
The bundle registers each cache's Freshen\AsyncHandler on Symfony's PSR-14
event_dispatcher, so invalidate() / invalidateExact() / refresh() (async by
default) dispatch Freshen\{Invalidate,InvalidateExact,Refresh}Event and are handled
without you wiring listeners.
Caveat — shared dispatcher fan-out. These events carry a key only, not a cache id, so an async
invalidate($key)is delivered to every configured cache's handler. Where a cache doesn't hold that key it's a harmless no-op, but caches that use colliding key namespaces would cross-invalidate. Give each cache a distinctKeydomain/facet (they naturally differ per dataset) and this is a non-issue.
Versioning
Independent SemVer, released as symfony-vX.Y.Z. Depends on vatvit/freshen-php via
^1.0@rc (→ ^1.0 once core is stable). A core patch/minor needs no bridge release; a
core major does. See the monorepo RELEASING.md.
Links
- Core library & full docs: https://github.com/vatvit/freshen (
packages/php) - Manual (non-bundle) wiring: the core README's "Framework integration" section.
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 3
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-07-11