You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+58-23Lines changed: 58 additions & 23 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,33 +1,38 @@
1
1
# Laravel Queue Debouncer
2
+
2
3
### Easy queue job debouncing
3
4
4
5
## Requirements
5
-
* Laravel >= 6.0
6
-
* An async queue driver
6
+
7
+
- Laravel >= 6.0
8
+
- An async queue driver
7
9
8
10
**Note:** v2.0 requires at least Laravel 6. For Laravel 5.5 ..< 6.0 support, check out [v1.0.2](https://github.com/mpbarlow/laravel-queue-debouncer/tree/1.0.2)
This package allows any queue job in your Laravel application to be debounced, meaning that no matter how many times it’s dispatched within the specified timeout window, it will only actually be ran once.
15
17
16
-
For example, imagine you want to send an email each time a user changes their contact details, but you don’t want to spam them if they make several changes in a short space of time. Debouncing the job with a five minute wait would ensure they only receive a single email, no matter how many changes they make within that five minutes.
18
+
This package allows any queue job or chain in your Laravel application to be debounced, meaning that no matter how many times it’s dispatched within the specified timeout window, it will only run once.
17
19
18
-
Version 2.0 is a complete rewrite and brings numerous improvements to the capabilities and ergonomics of the package, as well as thorough test coverage.
20
+
For example, imagine you dispatch a job to rebuild a cache every time a record is updated, but the job is resource intensive. Debouncing the job with a five minute wait would ensure that the cache is only rebuilt once, five minutes after you finish making changes.
19
21
20
22
## Usage
21
-
Debounced jobs can largely be treated like any other dispatched job. The debouncer takes two arguments, the actual `$job` you want to run, and the `$wait` period.
22
23
23
-
As with a regular dispatch, `$job` can be either a class implementing `Illuminate\Foundation\Bus\Dispatchable` or a closure. `$wait` accepts any argument that the `delay` method on a dispatch accepts (i.e. a `DateTimeInterface` or a number of seconds).
24
+
Debounced jobs can largely be treated like any other dispatched job. The debouncer takes two arguments, the actual `$job` you want to run, and the `$wait` period.
25
+
26
+
As with a regular dispatch, `$job` can be either a class implementing `Illuminate\Foundation\Bus\Dispatchable`, a chain, or a closure. `$wait` accepts any argument that the `delay` method on a dispatch accepts (i.e. a `DateTimeInterface` or a number of seconds).
24
27
25
28
The debouncer returns an instance of `Illuminate\Foundation\Bus\PendingDispatch`, meaning the debouncing process itself may be assigned to a different queue or otherwise manipulated.
26
29
27
30
### Calling the debouncer
28
-
There are several ways to initiate debouncing of a job:
31
+
32
+
There are several ways to use the debouncer:
29
33
30
34
#### Dependency Injection
35
+
31
36
```php
32
37
use App\Jobs\MyJob;
33
38
use Mpbarlow\LaravelQueueDebouncer\Debouncer;
@@ -45,6 +50,7 @@ class MyController
45
50
```
46
51
47
52
#### Facade
53
+
48
54
```php
49
55
use App\Jobs\MyJob;
50
56
use Mpbarlow\LaravelQueueDebouncer\Facade\Debouncer;
Of course, you may substitute the job class for a closure.
63
-
64
-
When monitoring the queue, you will see an entry for the package’s internal dispatcher each time the debounced job is queued, but the job itself will only run once, when the final wait time has expired.
69
+
When monitoring the queue, you will see an entry for the package’s internal dispatcher each time the debounced job is queued, but the job itself will only run once, when the final wait time has expired.
65
70
66
71
For example, assuming the following code was ran at exactly 9am:
67
72
@@ -102,7 +107,8 @@ Hello!
102
107
```
103
108
104
109
## Customising Behaviour
105
-
This package provides a few knobs and dials to customise things to your needs. To override the default behaviour, you should publish the config file:
110
+
111
+
This package provides a few hooks to customise things to your needs. To override the default behaviour, you should publish the config file:
This will copy `queue_debouncer.php` to your config directory.
112
118
113
119
### Cache key provider
114
-
To support multiple jobs being debounced, the package generates a unique key in the cache for each job type. This key is used as a lookup when the wait for a given dispatch expires, to determine whether the job should be ran or not.
115
120
116
-
The default implementation works as follows:
117
-
* For class-based jobs, use the fully-qualified class name
118
-
* For closure-based jobs, compute the SHA1 hash of a reflected representation of the closure
119
-
* Prepend the `cache_prefix` value from the config, separated by a colon (‘:’)
121
+
To identify the job being debounced, the package generates a unique key in the cache for each job type.
122
+
123
+
Two cache key providers are included:
124
+
125
+
-`Mpbarlow\LaravelQueueDebouncer\Support\CacheKeyProvider` (default): uses the config's `cache_prefix` value with either: the fully-qualified class name for class-based jobs; or a SHA1 hash of the closure for closure jobs.
126
+
-`Mpbarlow\LaravelQueueDebouncer\Support\SerializingCacheKeyProvider`: uses the config's `cache_prefix` value with a SHA1 hash of the serialized job. If you want to debounce jobs based on factors beyond their class name (for example, some internal state), this is the provider to use. This is also required if you need to debounce chains, as the default provider will debounce _all_ chains dispatched by your application as if they are the same job, regardless of what jobs are contained within.
127
+
128
+
Alternatively, you can provide your own class or closure to cover any other behaviour you might need:
120
129
121
-
If the default behaviour works for you, but you’d like to use a different cache prefix, you may simply override that value.
130
+
If you provide a class, it should implement `Mpbarlow\LaravelQueueDebouncer\Contracts\CacheKeyProvider`. Please note that your class is responsible for fetching and prepending the cache prefix should you still desire this behaviour.
122
131
123
-
Alternatively, you can provide your own class to produce a key for a given job. This is useful in cases where you have jobs that are implemented as different classes but should be considered the same job for the purposes of debouncing.
132
+
Class-based providers may be globally registered as the default provider by changing the `cache_key_provider` value in the config. Alternatively, you may "hot-swap" the provider using the `usingUniqueIdentifierProvider` method:
124
133
125
-
Your provider class must implement `Mpbarlow\LaravelQueueDebouncer\Contracts\CacheKeyProvider`. Please note that your class is responsible for fetching and prepending the cache prefix should you still desire this behaviour—it will not be added automatically.
**Note:** Because of the limited ways we have to produce a value representation of a closure, only the _exact same closure_ will produce the same cache key. So, while closures originating from the same line in the same file will produce the same key on subsequent requests, two closures with the same content dispatched from different places will not.
140
+
If you provide a closure, it may only be be hot-swapped:
141
+
142
+
```php
143
+
$debouncer
144
+
->usingCacheKeyProvider(fn () => 'my custom key')
145
+
->debounce($job, 10);
146
+
```
147
+
148
+
Closure providers automatically have their value prefixed by the configured `cache_prefix`. To override this behaviour, implement a class-based provider that accepts a closure in its constructor, then calls it in its `getKey` method.
128
149
129
150
### Unique identifier provider
130
-
Each time a debounced job is dispatched, a unique identifier is stored against the cache key for the job. When the wait time expires, if that identifier matches the value inserted, the debouncer knows that no more recent instances of the job have been dispatched, and therefore it is safe to dispatch it.
131
151
132
-
The default implementation produces a UUID v4 for each dispatch. If you need to override this you may do so via the config. As with the cache key provider, your class must implement `Mpbarlow\LaravelQueueDebouncer\Contracts\UniqueIdentifierProvider`.
152
+
Each time a debounced job is dispatched, a unique identifier is stored against the cache key for the job. When the wait time expires, if that identifier matches the value of the current job, the debouncer knows that no more recent instances of the job have been dispatched, and therefore it is safe to dispatch it.
153
+
154
+
The default implementation produces a UUID v4 for each dispatch. If you need to override this you may do so in the same manner as cache key providers, globally registering a class under the `unique_identifier_provider` key in the config, or hot-swapping using the `usingUniqueIdentifierProvider` method:
0 commit comments