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 spam and reduce queue load. Uses unique locks and caching to delay execution until activity stops. Tracks each request occurrence with reports including IP and authenticated user.

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. Basic Usage:

    • For jobs:
      use Zackaj\LaravelDebounce\Facades\Debounce;
      Debounce::job(new MyJob(), delay: 5, uniqueKey: auth()->id());
      
    • For notifications:
      Debounce::notification(
          notifiables: User::all(),
          notification: new MyNotification(),
          delay: 5,
          uniqueKey: 'global_key'
      );
      
    • For commands (Laravel 11+):
      Debounce::command(
          command: 'app:my-command',
          delay: 5,
          uniqueKey: $request->ip(),
          parameters: ['--option' => 'value']
      );
      
  3. First Use Case: Replace immediate notifications/jobs with debounced versions to reduce queue spam (e.g., bulk email sends or rate-limited actions).


Implementation Patterns

Workflows

  1. Debouncing Jobs:

    • Use Debounce::job() for queueable jobs.
    • Extend Zackaj\LaravelDebounce\DebounceJob for custom logic (e.g., hooks, timestamp overrides).
    • Example:
      class SendWelcomeEmail extends DebounceJob implements ShouldQueue {
          public function before(): void {
              Log::info('Preparing to send welcome email...');
          }
          public function handle() {
              // Send email logic
          }
      }
      
  2. Debouncing Notifications:

    • Use Debounce::notification() for bulk notifications.
    • Extend Zackaj\LaravelDebounce\DebounceNotification to access notifiables in hooks.
    • Example:
      class NewPostNotification extends DebounceNotification {
          public function before($notifiables): void {
              $this->logActivity($notifiables);
          }
      }
      
  3. Debouncing Commands:

    • Use Debounce::command() for CLI tasks (Laravel 11+).
    • Extend Zackaj\LaravelDebounce\DebounceCommand for static hooks.
    • Example:
      php artisan debounce:command 10 user_id app:generate-reports --force
      
  4. Report Tracking:

    • Access occurrence history via $debounceable->getReport()->occurrences.
    • Useful for debugging or analytics (e.g., track how often a user triggers a debounced action).

Integration Tips

  • Queue Workers: Ensure your queue worker is running to process debounced jobs.
  • Cache Driver: Use a cache driver that supports atomic locks (e.g., Redis, database).
  • Testing: Disable debouncing in tests via config(['debounce.enabled' => false]) or .env.testing.
  • Custom Timestamps: Override getLastActivityTimestamp() to debounce based on domain-specific logic (e.g., last message timestamp).

Gotchas and Tips

Pitfalls

  1. Cache Dependencies:

    • Flushing the cache clears all debounce reports and locks. Avoid Cache::flush() in production unless necessary.
    • Use Cache::forget() for specific keys if you need to reset individual debounces.
  2. Laravel Version Quirks:

    • Commands: Only supported in Laravel 11+. Use Debounce::command() or the debounce:command Artisan helper.
    • Notifications/Jobs: Works in Laravel 10+, but CLI debouncing is removed for Laravel 10 in v3.0.0.
  3. Hook Timing:

    • after() hooks may run before the debounceable is handled if it’s queued (e.g., ShouldQueue jobs/notifications with sync=false).
    • Example: A queued job’s after() hook fires when the job is dispatched, not when it’s processed.
  4. Unique Key Collisions:

    • Ensure uniqueKey is unique per debounceable type (e.g., user_id for notifications, ip for commands).
    • Avoid generic keys like 'global' unless intentional.

Debugging

  • Telescope: Use Laravel Telescope to monitor debounced jobs/commands in the "Queues" tab.
  • Report Inspection:
    $report = (new MyDebounceJob())->getReport();
    dd($report->occurrences->pluck('ip', 'happenedAt'));
    
  • Log Occurrences:
    public function before(): void {
        Log::debug('Debounce triggered', [
            'key' => $this->getUniqueKey(),
            'occurrences' => $this->getReport()->occurrences->count(),
        ]);
    }
    

Extension Points

  1. Custom Drivers:

    • Extend the package to support non-cache drivers (e.g., database locks) by implementing Zackaj\LaravelDebounce\Contracts\DebounceDriver.
  2. Dynamic Delays:

    • Override getDelay() in your debounceable to calculate delays dynamically:
      public function getDelay(): int {
          return $this->user->preferences->debounce_delay ?? 5;
      }
      
  3. Event Listeners:

    • Listen for Zackaj\LaravelDebounce\Events\DebounceableDispatched to react to debounced actions:
      event(new DebounceableDispatched($debounceable));
      
  4. CLI Debounce:

    • For Laravel 10, manually debounce commands using the facade:
      Debounce::command('app:command', delay: 10, uniqueKey: 'cli_key');
      
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport