cache/filesystem-adapter
PSR-6 and PSR-16 cache pools backed by Flysystem 2.x and 3.x. FilesystemCachePool stores SHA-256 hashed keys in 256 shard directories for portable filenames and smaller directories, with configurable cache folders, filesystem accessors, and custom layouts via getFilePath().
Architecture fit. cache/filesystem-adapter is a PSR-6 pool that delegates storage to a Flysystem Filesystem. In a Laravel context that is a layer Laravel already owns: Laravel ships a first-class file cache store (config/cache.php → driver => 'file'), a Cache facade, PSR-16 bindings, and Flysystem 3.x underneath Storage. Adopting this package means maintaining a parallel caching abstraction that duplicates framework behaviour rather than extending it. The one genuinely differentiated capability is PSR-6-compliant caching over an arbitrary Flysystem mount (e.g., object storage, remote mount), which Laravel's file driver does not offer. Frame the evaluation around whether that niche is a real product requirement or an architectural curiosity.
Integration feasibility. Low to moderate, and gated on a compatibility unknown. The README usage example imports League\Flysystem\Adapter\Local, an API removed in Flysystem 2.0; Laravel 10/11/12 ship Flysystem 3.x (League\Flysystem\Local\LocalFilesystemAdapter). Either the package is pinned to Flysystem 1.x (which will conflict with Laravel's composer constraints) or the README is stale while internals were updated — unverifiable from the supplied artefacts. Second gap: PSR-6 has no increment/decrement, no key prefixing, and different clear() semantics than Illuminate\Contracts\Cache\Store. Any Laravel integration requires a custom store class implementing get, many, put, putMany, increment, decrement, forever, forget, flush, and getPrefix — with increment necessarily implemented as a non-atomic read-modify-write.
Technical risk. High.
composer show/Packagist verification before any decision.addItem/deleteItem races and clear() scoped to a folder can wipe overlapping pools.DateTimeInterface/integer TTLs, prefixed keys, and graceful degradation on store failure; PSR-6 pools throw CacheException on I/O faults. Without an explicit try/catch boundary, a full disk or permission error becomes a 500.Key questions for the decision review.
file driver fail — cold-start config caching, fragment caching, third-party API response caching? Name the workload and its TTL/concurrency profile.symfony/cache (FilesystemAdapter, PSR-6 + PSR-16, maintained) is the stronger candidate.Stack fit. Poor for a standard Laravel application; defensible only in two narrow cases: (a) framework-agnostic PHP packages/services in the same estate that must share a PSR-6 contract with the Laravel app, and (b) a need for cache storage on a non-local Flysystem mount. If neither applies, recommend no integration and close the ticket with a documented rationale, because "we can" is not a reason to replace a battle-tested framework driver.
Migration path (if approved). Timeboxed and reversible:
composer why-not. Deliverable: go/no-go memo with the actual resolved version matrix.App\Cache\FilesystemPoolStore implements Illuminate\Contracts\Cache\Store delegating to FilesystemCachePool, with explicit try/catch → cache-miss degradation and a documented non-atomic increment.config/cache.php (e.g., flysystem), and consume it only through the Cache facade / repository contract so the underlying driver is swappable without touching call sites.file or redis.Compatibility. Verify against the actual application matrix, not the README: PHP 8.1–8.3, Laravel 10–12, league/flysystem ^3.0, and composer audit output. Note Laravel's cache layer expects string-serialisable values consistent with its own serializer — mismatched serialisation between the PSR-6 pool and other stores will produce cross-driver cache misses during any phased rollout.
Sequencing. Never on the critical path. Land it after the release currently in flight, as an opt-in named store, with the default unchanged. Sequence: spike → decision gate → adapter + tests → canary on one low-risk cache namespace (e.g., a read-heavy reference-data cache with long TTL) → wider adoption only if it beats the incumbent on a measured metric.
Effort envelope for planning: ~5–8 engineer-days including tests, plus recurring ownership cost. Compare against ~0 days for Laravel's file driver and ~1 day for symfony/cache if PSR-6 is mandatory.
Maintenance. The package is READ-ONLY with no active release cadence and negligible adoption. Budget for fork-and-vendor-patch capability (vcs repository entry or a Composer patch plugin) and assign a named owner. If that owner cannot be named, the correct TPM recommendation is to decline adoption — unowned dependencies are how incidents happen six months later.
Support. No upstream SLA, dormant community channel, no issue triage. Internal support must come from the owning team's runbook: how to inspect the cache folder, how to flush a single pool safely, how to identify stale tag directories. Add a runbook entry and an alert on cache-directory size.
Scaling. Single-node only. Horizontal scaling is possible only if all nodes share the mount, which introduces NFS/network-locking caveats and effectively serialises writes. The Flysystem-remote variant trades disk contention for network latency on every read — quantify this before promising performance. There is no eviction policy: disk grows until something clears it, so a scheduled GC or TTL-sweep job is a launch prerequisite, not a follow-up.
Failure modes to instrument.
increment-style counters; prohibit counters on this store.clear() scoped to a folder → cross-pool wipe when setFolder() paths overlap; enforce per-pool folder isolation in config review.Ramp-up. The package API itself is trivial (sub-day). The real ramp is Flysystem 3 idioms plus Laravel's Store contract internals — roughly 3–5 days for a mid-level engineer to be productive and safe. Ramp risk concentrates on the absence of documentation, not conceptual difficulty.
Programme recommendation. Treat as a conditional no-go: default to Laravel's native file driver (or redis where concurrency and multi-node correctness matter), and re-open only if the PSR-6-over-Flysystem niche is confirmed as a hard requirement — in which case symfony/cache's FilesystemAdapter should be evaluated head-to-head first and the outcome recorded so this doesn't get re-litigated next quarter.
How can I help you explore Laravel packages today?