There is no easy or %100 working way to remove duplicated job. Laravel's Redis queue driver uses sorted sets and lists for delayed/non-delayed jobs. This answer may provide some details about it. When you push the job into the queue then you can't remove it before it is processed. (you can try, but it is hard, the link has the answers).
What you may do is creating a control mechanism to prevent triggering cache invalidating job. Let's say before you push your job, you set a unique identifier. You may use Redis's SET command with EX
and NX
option.
- Set key to hold the string value. If key already holds a value, it is overwritten, regardless of its type.
- NX -- Only set the key if it does not already exist.
- EX seconds -- Set the specified expire time, in seconds.
Before you push your job you execute the first command something like this;
127.0.0.1:6379> set mymodel:id:1 some-random-string-test EX 15 NX
OK
127.0.0.1:6379> ttl mymodel:id:1
(integer) 10
127.0.0.1:6379> get mymodel:id:1
"some-random-string-test"
127.0.0.1:6379> set mymodel:id:1 some-random-string-test-another EX 15 NX
(nil)
127.0.0.1:6379>
What you are doing is, you get the id
of your model and create a key. You set your key with expire and set if not exists
option. If the response is OK
then you are setting this key for the first time in the given time interval(15 seconds in my example). If you get nil
response it means that, the job for the given id is still locked
. So you won't dispatch it. It will provide you a 15 seconds time window for each model that will prevent you to dispatch it.
--
If you can't(don't want) prevent the job to be triggered, then you can use the same command in a different way. Whenever you are about the dispatch the job you create a unique identifier and execute set mymodel:id:1 some-random-string-test EX 15 NX
before dispatching it. But this time you will send identifier to the job's constructor too. At the beginning of your handle
method, you will use redis's GET
method to get the value of mymodel:id:1
and compare it with the identifier that you sent to the job's constructor. There will be only 1 matching identifier in 15 seconds, that means only one job will be "fully" processed. The other identifiers created for the same jobs will not be updating the the value of that redis key(NX option), therefore other job's identifier will not matched with the value of mymodel:id:1
. That means they will be cancelled or not fully processed because they will not pass the condition.