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

Laravel Debounce Laravel Package

zackaj/laravel-debounce

Debounce Laravel jobs, notifications, and (Laravel 11+) Artisan commands to prevent spamming users and queues. Uses unique job locks + cache to delay execution until activity stops. Tracks each occurrence with request metadata (IP, user) and provides reporting.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require zackaj/laravel-debounce
    

    Publish config (optional):

    php artisan vendor:publish --tag=laravel-debounce-config
    
  2. First Use Case: Debounce a notification in a controller:

    use Zackaj\LaravelDebounce\Facades\Debounce;
    
    Debounce::notification(
        notifiables: $users,
        notification: new FileUploaded($file),
        delay: 5, // seconds
        uniqueKey: auth()->user()->id
    );
    

Where to Look First

  • Facade Usage: Zackaj\LaravelDebounce\Facades\Debounce for quick integration.
  • Configuration: config/debounce.php for enabling/disabling globally.
  • Report Tracking: Extend DebounceJob, DebounceNotification, or DebounceCommand for tracking.

Implementation Patterns

Core Workflows

  1. Debouncing Jobs:

    // Using facade
    Debounce::job(new ProcessPayment($order), delay: 10, uniqueKey: $order->id);
    
    // Using job instance (extend DebounceJob)
    (new ProcessPayment($order))->debounce(delay: 10, uniqueKey: $order->id);
    
  2. Debouncing Notifications:

    // Using facade
    Debounce::notification(
        notifiables: $users,
        notification: new WelcomeNotification(),
        delay: 30,
        uniqueKey: 'welcome_'.$user->id
    );
    
    // Using notification instance (extend DebounceNotification)
    (new WelcomeNotification())->debounce($users, delay: 30, uniqueKey: 'welcome_'.$user->id);
    
  3. Debouncing Artisan Commands (Laravel ≥11):

    // Using facade
    Debounce::command(
        command: 'report:generate',
        delay: 60,
        uniqueKey: 'daily_report',
        parameters: ['--format' => 'pdf']
    );
    
    // CLI debounce (Laravel ≥11)
    php artisan debounce:command 60 daily_report report:generate --format=pdf
    

Integration Tips

  • Queue Sync: Set sync: false (default) to dispatch jobs to the queue.
  • Report Tracking: Extend base classes to access occurrence history:
    $report = $this->getReport();
    $report->occurrences->first()->ip; // Track IP
    $report->occurrences->first()->user; // Track authenticated user
    
  • Custom Timestamps: Override getLastActivityTimestamp() for dynamic debouncing:
    public function getLastActivityTimestamp(): ?Carbon
    {
        return $this->model->updated_at;
    }
    

Hooks for Side Effects

  • Jobs/Notifications:
    public function before(): void { /* Pre-execution logic */ }
    public function after(): void { /* Post-execution logic */ }
    
  • Commands (static methods):
    public static function before(): void { /* CLI pre-execution */ }
    public static function after(): void { /* CLI post-execution */ }
    

Gotchas and Tips

Pitfalls

  1. Cache Dependency:

    • Reports and locks are stored in cache. Flushing cache (php artisan cache:clear) resets all debounced tasks.
    • Workaround: Use a persistent cache driver (e.g., Redis) for production.
  2. Laravel Version Quirks:

    • Artisan Commands: Only supported in Laravel ≥11. Older versions throw errors.
    • Workaround: Use facade-based debouncing for commands in Laravel <11.
  3. Hook Timing:

    • after() hooks may fire before queue dispatch if sync: false is set for queued jobs/notifications.
    • Tip: Use after() for post-queue logic (e.g., logging) or move critical logic to handle()/toArray().
  4. Unique Key Collisions:

    • Poorly chosen uniqueKey values (e.g., static strings) may cause unintended merging of unrelated tasks.
    • Tip: Use dynamic keys tied to context (e.g., user_id, order_id).

Debugging Tips

  • Telescope Integration: Monitor debounced tasks in Laravel Telescope’s Queues tab.

    // Enable Telescope monitoring
    $this->getReport()->occurrences->each(function ($occurrence) {
        \Illuminate\Support\Facades\Log::info('Debounce event', $occurrence->toArray());
    });
    
  • Testing: Disable debouncing globally in tests:

    config(['debounce.enabled' => false]);
    

    Or per-test:

    $this->app->singleton('debounce', fn() => new \Zackaj\LaravelDebounce\DebounceManager(false));
    

Extension Points

  1. Custom Drivers: Extend Zackaj\LaravelDebounce\Contracts\DebounceDriver to support non-cache backends (e.g., database).

  2. Report Enhancements: Override getReport() in base classes to add custom metadata:

    public function getReport(): DebounceReport
    {
        return parent::getReport()->withMetadata(['custom_field' => $this->value]);
    }
    
  3. Dynamic Delays: Implement logic in getDelay() to adjust delays per context:

    public function getDelay(): int
    {
        return $this->isUrgent() ? 1 : 30;
    }
    

Performance Considerations

  • High-Volume Systems:
    • Use Redis for cache to reduce lock contention.
    • Monitor cache:lock TTLs to avoid timeouts during spikes.
  • Long-Running Tasks:
    • Avoid excessive delays (>60s) to prevent stale locks.
    • Tip: Use now()->addMinutes(1) for delays >60s.
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.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
ecotone/kafka
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata