Lets learn how to skip jobs using Skip middleware. Skip middleware support two method as when() and unless().
- When()
- Skip the job when it return true.
- If return true job will be not executed.
- unless()
- Skip the job when it return false.
- If return false job will not execute.
Example of using When() and Unless()
Testing use of when() method and unless() in a complete Laravel example.
Task: Create a Laravel application that activate subscription based on user information.
– Use when() method to not to activate subscriptions for active users.
– Use unless() method to activate subscription for active users.
Here you must return true on both methods to archive above goal.
Setup
Setup a fresh Laravel application. Use Laravel documention for help.
Create a job class
Create a sample job class called ActivateSubscription using below artisan command.
php artisan make:job ActivateSubscription
Open created job class and add below code. Modify constructor method to accept user object.
<?php
namespace App\Jobs;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Support\Facades\Log;
class ActivateSubscription implements ShouldQueue
{
use Queueable;
/**
* Create a new job instance.
*/
public function __construct(public object $user)
{}
/**
* Execute the job.
*/
public function handle(): void
{
Log::info("Completed the Job for {$this->user->name}");
}
}
Dispatch the Job
Open web.php file and modify.
- Create two users with “name” and “active” attributes.
- One user with true and other with false on active field.
- Dispatch the job twice using both users.
<?php
use App\Jobs\ActivateSubscription;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
Log::info("Received a get request on root route");
//Active user
$user1 = new stdClass();
$user1->name = "Dave";
$user1->active = true;
//Not active user
$user2 = new stdClass();
$user2->name = "mark";
$user2->active = false;
ActivateSubscription::dispatch($user1);
ActivateSubscription::dispatch($user2);
});
Run Laravel application
php artisan serve
Run a queue worker
php artisan queue:work
Check Laravel Logs. You will see both jobs executed successfully.
[2024-12-22 11:25:24] local.INFO: Received a get request on root route
[2024-12-22 11:25:25] local.INFO: Completed the Job for Dave
[2024-12-22 11:25:25] local.INFO: Completed the Job for mark
Using when() method to skip jobs
Add Skip middleware to the job class. Here we are using a closure inside the when() method pass the true/false condition.
<?php
namespace App\Jobs;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Queue\Middleware\Skip;
use Illuminate\Support\Facades\Log;
class ActivateSubscription implements ShouldQueue
{
use Queueable;
/**
* Create a new job instance.
*/
public function __construct(public object $user)
{}
/**
* Execute the job.
*/
public function handle(): void
{
Log::info("Completed the Job for {$this->user->name}");
}
public function middleware():array
{
//Do not run this job if user is active
//Skip if return true
return [
Skip::when(fn () => $this->user->active)
];
}
}
Make sure to restart the queue worker. Check Logs file. You will see that active users are not executed. Because when() method skip true conditions (active=true)
[2024-12-22 11:29:54] local.INFO: Received a get request on root route
[2024-12-22 11:29:56] local.INFO: Completed the Job for mark
Using unless() method to skip jobs
Add Skip middleware to job class and use unless() method to skip jobs that return false. Here jobs of active users are executed and others were skipped.
<?php
namespace App\Jobs;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;
use Illuminate\Queue\Middleware\Skip;
use Illuminate\Support\Facades\Log;
class ActivateSubscription implements ShouldQueue
{
use Queueable;
/**
* Create a new job instance.
*/
public function __construct(public object $user)
{}
/**
* Execute the job.
*/
public function handle(): void
{
Log::info("Completed the Job for {$this->user->name}");
}
public function middleware():array
{
//Do not run this job only if user is not active
//skip if return false.
return [
Skip::unless(fn () => $this->user->active)
];
}
}
Restart the queue worker and test the result. You will see only the jobs of users with active true are executed.
[2024-12-22 11:33:59] local.INFO: Received a get request on root route
[2024-12-22 11:33:59] local.INFO: Completed the Job for Dave