Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Flysystem Cached Extra Laravel Package

nao-pon/flysystem-cached-extra

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require nao-pon/flysystem-cached-extra
    
  2. Basic Setup: Extend Laravel’s CachedAdapter with the provided traits in a service provider:

    use NaoPon\FlysystemCachedExtra\Traits\{TemporaryFileTrait, FileLockingTrait};
    use League\Flysystem\Cached\CachedAdapter;
    
    // In a service provider's boot method
    $this->app->extend('filesystem', function ($filesystem) {
        $adapter = $filesystem->getAdapter();
        if ($adapter instanceof CachedAdapter) {
            $adapter->useTrait(TemporaryFileTrait::class);
            $adapter->useTrait(FileLockingTrait::class);
        }
        return $filesystem;
    });
    
  3. First Use Case: Use the TemporaryFileTrait for job payloads or the FileLockingTrait for concurrent writes:

    // Create a temporary file (auto-expires after 1 hour)
    Storage::disk('cached_temp')->put('temp/job-123.json', $data);
    
    // Lock a file for exclusive access
    Storage::disk('cached_temp')->lock('critical-file.txt', function () {
        // Critical section
    });
    

Implementation Patterns

Core Workflows

  1. Temporary File Handling:

    // Set TTL (e.g., 1 hour)
    Storage::disk('cached_temp')->put('temp/file.txt', 'content', [
        'cache_ttl' => 3600,
    ]);
    
    // Manually expire early
    Storage::disk('cached_temp')->expire('temp/file.txt');
    
  2. File Locking:

    // Lock with timeout (5 seconds)
    Storage::disk('cached_temp')->lock('file.txt', 5, function () {
        // Exclusive access block
    });
    
    // Check if locked
    if (Storage::disk('cached_temp')->isLocked('file.txt')) {
        // Handle contention
    }
    
  3. Streaming Support:

    // Stream a large file with caching
    $stream = Storage::disk('cached_temp')->readStream('large-file.zip');
    // Process stream...
    
  4. Integration with Queues:

    // In a job
    public function handle()
    {
        $tempPath = 'temp/' . $this->jobId . '.json';
        Storage::disk('cached_temp')->put($tempPath, $this->payload, [
            'cache_ttl' => 3600,
        ]);
        // Process...
        Storage::disk('cached_temp')->delete($tempPath);
    }
    

Laravel-Specific Patterns

  • Dynamic Disks:

    Storage::extend('cached_temp', function ($app) {
        $adapter = new CachedAdapter(
            Storage::disk('s3')->getAdapter(),
            new TemporaryFileTrait(),
            new FileLockingTrait()
        );
        return new Filesystem($adapter);
    });
    
  • Event Listeners:

    // Invalidate cache on file deletion
    Storage::disk('cached_temp')->addListener('deleted', function ($path) {
        Cache::forget("flysystem_{$path}");
    });
    

Gotchas and Tips

Common Pitfalls

  1. Lock Contention:

    • Issue: FileLockingTrait uses flock (process-local). Distributed locks require Redis or database.
    • Fix: Replace with a custom trait using RedisLock or DatabaseLock.
  2. Memory Leaks:

    • Issue: Cached adapters hold files in memory. Large files (>100MB) can bloat RAM.
    • Fix: Set conservative cache_ttl or use file cache driver.
  3. Cache Stampedes:

    • Issue: Concurrent has() calls may flood the cache layer.
    • Fix: Use hasWithCacheValidation() with a short TTL (e.g., 5 minutes).
  4. Trait Conflicts:

    • Issue: Multiple traits may override the same methods (e.g., generateCacheKey).
    • Fix: Merge traits or use composition over inheritance.

Debugging Tips

  • Cache Inspection:

    // Dump cache stats
    dd(Storage::disk('cached_temp')->getAdapter()->getCache()->stats());
    
  • Lock Debugging:

    // Check active locks
    $locks = Storage::disk('cached_temp')->getAdapter()->getLocks();
    
  • TTL Validation:

    // Verify TTL for a file
    $metadata = Storage::disk('cached_temp')->getMetadata('temp/file.txt');
    $expiresAt = $metadata['cache_ttl'] ? now()->addSeconds($metadata['cache_ttl']) : null;
    

Extension Points

  1. Custom Cache Drivers:

    $adapter->setCache(new \League\Flysystem\Cached\Storage\Psr6CacheStorage(
        new \Illuminate\Cache\RedisStore()
    ));
    
  2. Override Traits:

    class CustomTemporaryFileTrait extends TemporaryFileTrait
    {
        protected function getDefaultTtl(): int
        {
            return 7200; // 2 hours
        }
    }
    
  3. Event Hooks:

    // Listen for cache misses
    Storage::disk('cached_temp')->getAdapter()->addListener('cache_miss', function ($path) {
        Log::debug("Cache miss for {$path}");
    });
    

Configuration Quirks

  • filesystems.php:

    'disks' => [
        'cached_temp' => [
            'driver' => 'custom',
            'adapter' => NaoPon\FlysystemCachedExtra\CachedAdapter::class,
            'cache' => env('FILESYSTEM_CACHE', 'file'), // 'redis', 'array', or 'file'
            'traits' => [
                NaoPon\FlysystemCachedExtra\Traits\TemporaryFileTrait::class,
                NaoPon\FlysystemCachedExtra\Traits\FileLockingTrait::class,
            ],
        ],
    ],
    
  • Environment Variables:

    FILESYSTEM_CACHE=redis
    FILESYSTEM_CACHE_TTL=3600
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope