sofascore/purgatory-bundle
A Symfony bundle from Sofascore for purging Doctrine entities after a configurable retention period. Define purge rules, schedule cleanup, and automatically remove stale or expired records with minimal configuration and Symfony-native integration.
Architecture fit — unchanged: poor as a drop-in, moderate as a pattern source. v2.0.2 changes nothing about the framework mismatch. In fact it reinforces it: the changelog names VarnishPurger, AsyncPurger, and TraceablePurger, and the fix list references TransportExceptionInterface (Symfony's HTTP client exception contract) and iterator_to_array key preservation in a traceable/debug purger. That is a Symfony-idiomatic component set — HTTP client contracts, an async dispatch layer (very likely Symfony Messenger), and a profiler-integrated decorator. None of that is honored by Laravel's container, queue, or package auto-discovery. The usable asset remains the domain logic: tag registry plus backend adapters translating tags into Varnish PURGE/BAN. Assume a port.
Second-order caching-topology concern is unchanged. Value remains proportional to running Varnish with tag/ban support; Fastly, Cloudflare, or Akamai edges inherit only the tag-management ideas. Confirm before investing.
Integration feasibility — unchanged in cost, slightly improved in clarity. The release is useful primarily as specification detail. It confirms the package has, at minimum: a synchronous Varnish transport purger, an async purger that batches/iterates tags into messages, and a traceable decorator for observability. Those map cleanly onto a Laravel port — Illuminate\Support\Facades\Http for transport, a queued job for async, and a logging/null decorator for the shadow-mode stage we already planned. The bounded 2–4 week build estimate holds. Consuming it as a dependency remains non-viable.
Technical risk — marginally improved on maintenance, still elevated overall. Positive signal: an active patch release with three fixes from a named external contributor, not just the sponsoring vendor. That is a healthier cadence signal than the prior assessment could assume, and it confirms the 2026-10-09 metadata is accurate rather than stale. Countervailing signal: all three fixes are on failure and edge paths — an uncaught transport exception, an empty-message dispatch for empty iterables, and key preservation in a debug decorator. Those are exactly the paths a cache invalidator lives or dies on, and their presence in a 2.0.x patch suggests the failure path is comparatively under-tested relative to the happy path. 119 stars, single-sponsor stewardship, and no SLA are unchanged. MIT license still makes forking unencumbered, and we would own the fork.
Key questions (revised; resolved items noted)
VarnishPurger clearly sits on Symfony's HTTP client contract; adapter seam exists but is Symfony-shaped)AsyncPurger exists and now guards against dispatching empty messages; retry/backoff and per-backend isolation still unverified. Check whether AsyncPurger is built on Symfony Messenger, which would deepen entanglement.)TraceablePurger emit enough structured detail (tags, backend, outcome, latency) to serve as the template for our shadow-mode decorator?Stack fit. Unchanged. Highest fit if the application were Symfony + Varnish — it is not. Adoption-as-dependency: near-zero. Adoption-as-reference: good, and this release improves the reference by documenting real failure-path behavior.
Migration path — four options, in preference order (unchanged).
CacheInvalidator service, tag registry driven by Eloquent and domain events, backend contract with a Varnish adapter, queued PurgeTags job, config for endpoints and credentials. Use v2.0.2 source as the specification, and port the fixed semantics, not the pre-fix behavior.TransportExceptionInterface fix indicates at least one adapter is bound to Symfony's HTTP client contract, which weakens this option. Re-evaluate only after reading the source.Compatibility. Unchanged: check PHP constraint against runtime, Symfony component versions against illuminate/*, and PSR-18/PSR-7 usage. If vendoring any code, pin to a commit SHA — specifically the v2.0.2 tag or later, since 2.0.1 carries a known uncaught transport exception and an empty-message dispatch bug we do not want to replicate.
Sequencing. Unchanged, with one insertion.
TraceablePurger.Maintenance. Unchanged in magnitude, slightly improved in confidence. A 119-star, single-sponsor package still is not something to track passively — budget ~0.1–0.2 FTE for a first-party fork or port plus review of upstream changes worth cherry-picking. Pin versions and mirror the source internally. Treat this patch release as one data point of health, not a trend.
Support. Community-only, no SLA, upstream priorities are Sofascore's. Escalation is a GitHub issue. Acceptable for a ported pattern we own; unacceptable for a production dependency on the critical path of cache correctness.
Scaling. Unchanged: purge volume and tag granularity (batch and coalesce per request cycle), Varnish ban-list growth (expire bans, prefer xkey over regex bans), and queue depth during deploys or bulk imports. The AsyncPurger empty-iterable fix is a small reminder that batching layers generate their own noise — guard our implementation against dispatching empty or duplicate purge batches, which inflate queue depth and backend load without invalidating anything.
Failure modes.
Ramp-up. Unchanged: two to three weeks for a mid-level engineer, dominated by HTTP caching mental models (surrogate keys, ban vs. purge semantics, TTL interaction) rather than the package. Enablement required: written tag taxonomy with owners, a "content is stale" runbook, and local Varnish in the dev environment.
Recommendation. Unchanged at ~20.9 with an opportunity score of 1.78. v2.0.2 is a maintenance patch — no breaking changes, no new features, no deprecations — so it does not alter the adoption calculus. It does modestly improve the maintenance signal, partially answer open questions about async purging and transport error handling, and sharpen the port specification. Use it as a design reference, port the tag-and-backend model into a small first-party Laravel package, and revisit only if the platform standardizes on Symfony or the package gains a framework-agnostic core.
How can I help you explore Laravel packages today?