Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/zackaj/laravel-debounce
a laravel package that gives you a debounce effect on jobs, notifications and artisan commands with a nice report of occurrences.
https://github.com/zackaj/laravel-debounce
artisan-commands composer laravel notifications package php queues
Last synced: about 2 months ago
JSON representation
a laravel package that gives you a debounce effect on jobs, notifications and artisan commands with a nice report of occurrences.
- Host: GitHub
- URL: https://github.com/zackaj/laravel-debounce
- Owner: zackAJ
- License: mit
- Created: 2024-11-09T16:00:09.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2024-11-12T21:26:22.000Z (3 months ago)
- Last Synced: 2024-12-14T06:14:08.078Z (about 2 months ago)
- Topics: artisan-commands, composer, laravel, notifications, package, php, queues
- Language: PHP
- Homepage: https://packagist.org/packages/zackaj/laravel-debounce
- Size: 33.2 KB
- Stars: 23
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE.md
Awesome Lists containing this project
README
![logo](https://github.com/user-attachments/assets/b30c65c0-f28b-41c9-a231-ad46e6699c8b)
# Laravel debounce
_by zackaj_Laravel-debounce allows you to accumulate / debounce a job,notification or command to avoid spamming your users and your app's queue.
It also tracks and registers every request occurrence and gives you a nice [report tracking](#report-tracking) with information like `ip address` and `authenticated user` per request.
# Table of Contents
- [Introduction](#introduction)
- [Features](#features)
- [Demo](#demo)- [Installation](#installation)
- [Prerequisites](#prerequisites)
- [Composer](#composer)- [Usage](#usage)
- [Basic usage](#basic-usage)
- [Advanced usage](#advanced-usage)
- [Make commands](#make-commands)
- [No facade usage](#no-facade-usage)
- [Report Tracking](#report-tracking)
- [Before After Hooks](#before-after-hooks)
- [Override Timestamp](#override-timestamp)- [Bonus CLI Debounce](#bonus-cli-debounce)
- [Debugging And Monitoring](#debugging-and-monitoring)
- [Known Issues](#known-issues)
- [Contributing](#contributing)
- [License](#license)## Introduction
This laravel package uses UniqueJobs (atomic locks) and caching to run only one instance of a task in a debounced interval of x seconds delay.
Everytime a new activity is recoreded (occurrence), the execution is delayed with x seconds.
### Features
- Debounce Notifications, Jobs and Artisan Commands [Basic usage](#basic-usage) & [Advanced usage](#advanced-usage)
- [Report Tracking](#report-tracking)
- [Bonus CLI Debounce](#bonus-cli-debounce)### Demo
A debounced notification to bulk notify users about new uploaded files.
https://github.com/user-attachments/assets/b1d5aafd-256d-4f6f-b31a-0d6dc516793b
See Code
FileUploaded.php
```php
$this->file->user->files()
->where('created_at', '>=', $this->file->created_at)
->get(),
];
}
}```
DemoController.php
```php
user();
$file = File::factory()->create(['user_id' => $user->id]);
$otherUsers = User::query()->whereNot('id', $user->id)->get();Notification::send($otherUsers, new FileUploaded($file));
return back();
}public function debounceNotification(Request $request)
{
$user = $request->user();
$file = File::factory()->create(['user_id' => $user->id]);
$otherUsers = User::query()->whereNot('id', $user->id)->get();Debounce::notification(
notifiables: $otherUsers,
notification:new FileUploaded($file),
delay: 5,
uniqueKey:$user->id,
);return back();
}
}
```## Installation
### Prerequisites
- Laravel application (11.x , 10.x should be fine)
- Up and running cache system that supports [atomic locks](https://laravel.com/docs/11.x/cache#atomic-locks)
- Up and running [queue worker](https://laravel.com/docs/11.x/queues)### Composer
```bash
composer require zackaj/laravel-debounce
```## Usage
### Basic usage
You can debounce existing jobs, notifications and commands with zero setup.**Warning** you can't access report or track the requests without extending the package's classes, see [Advanced usage](#advanced-usage)
```php
use Zackaj\LaravelDebounce\Facades\Debounce;//job
Debounce::job(
job:new Job(),//replace
delay:5,//delay in seconds
uniqueKey:auth()->user()->id,//debounce per Job class name + uniqueKey
sync:false, //optional, job will be fired to the queue
);//notification
Debounce::notification(
notifiables: auth()->user(),
notification: new Notification(),//replace
delay: 5,
uniqueKey: auth()->user()->id,
sendNow: false,
);//command
Debounce::command(
command: new Command(),//replace
delay: 5,
uniqueKey: $request->ip(),
parameters: ['name' => 'zackaj'],//see Artisan::call() signature
toQueue: false,//optional, send command to the queue when executed
outputBuffer: null,//optional, //see Artisan::call() signature
);
```## Advanced usage
In order to use:
- [No Facade Usage](#no-facade-usage)
- [Report Tracking](#report-tracking)
- [before/after Hooks](#before-after-hooks)
- [Debounce from custom timestamp](#override-timestamp)your existing jobs, notificaitons and commands must extend:
```php
use Zackaj\LaravelDebounce\DebounceJob;
use Zackaj\LaravelDebounce\DebounceNotification;
use Zackaj\LaravelDebounce\DebounceCommand;
```or just generate new ones using the available [make commands](#make-commands).
### Make commands
- Notification
```bash
php artisan make:debounce-notification TestNotification
```- Job
```bash
php artisan make:debounce-job TestJob
```- Command
```bash
php artisan make:debounce-command TestCommand
```### No facade usage
Alternatively, now you can debounce from the job, notification and command instances directly without using the `Debounce facade` used in [Basic usage](#basic-usage)```php
(new Job())->debounce(...);(new Notification())->debounce(...);
(new Command())->debounce(...);
```### Report Tracking
Laravel-debounce uses the cache to store every request occurrence, use `getReport()` method within your debounceables to access the report chain that has a collection of occurrences.Every report will have one occurrence minimum.
```php
getReport()->occurrences;//collection of occurrences
$this->getReport()->occurrences->count();
$this->getReport()->occurrences->first()->happenedAt;
$this->getReport()->occurrences->first()->ip;
$this->getReport()->occurrences->first()->ips;
$this->getReport()->occurrences->first()->requestHeaders;//HeaderBag
$this->getReport()->occurrences->first()->user;//authenticated user | null
}
}```
### Before After Hooks
If you wish to run some code before and/or after firing the `debounceables` you can use the available hooks.**Important:** `after()` hook could run before your `debounceable` is handled if it's `sent to the queue` when:
- `sendNow==false` and your notification `implements ShouldQueue`
- `sync==false` and your job `implements ShouldQueue`
- `toQueue==true` (command)see: [Basic usage](#basic-usage)
#### Debounce job
```php
getReport()->occurrences->last()->happenedAt;
}
```You can override this method in your `debounceables` in order to debounce from a custom timestamp of choice, if null returned the debouncer will fallback to the default implementation above.
#### Debounce job
```php
first()?->seen_at;
}
}
```#### Debounce notification
You get the `$notifiables` injected into the method.```php
file->user->files->latest()->first()?->created_at;
}
}
```#### Debounce command
Due to limitations, the method must be `static`.```php
first()?->created_at;
}
}```
## Bonus CLI Debounce
For fun, you can actually debounce commands from the CLI using `debounce:command` Artisan command.```php
php artisan debounce:command 5 uniqueKey app:test
```
here's the signature for the command:
`php artisan debounce:command {delay} {uniqueKey} {signature*}`## Debugging And Monitoring
I recommend using [Laravel telescope](https://laravel.com/docs/11.x/telescope) to see the debouncer live in queues tab and to debug any failures.## Known Issues
1- Unique lock gets stuck sometimes when jobs fail [github issue](https://github.com/laravel/framework/issues/37729)
- cause: this happens when deleted models are unserialized causing the job to fail without clearing the lock.
- solution: If you're using `database` cache driver delete the entry from job_locks table.
## Contributing
Contributions, issues and suggestions are always welcome! See `contributing.md` for ways to get started.
## License
[MIT](https://choosealicense.com/licenses/mit/)