- Overview
- Setup
- Allowed Jobs
- Creating Jobs
- Running Jobs
- Retry Logic Configuration
- Example Usage
- Advanced features
- Final notes
This is a custom lightweight background job runner for Laravel projects, without using Laravel’s default queue system.
It supports retry logic, whitelisting allowed jobs and methods, and manual CLI job execution.
Follow these steps to get started:
- PHP 8.1+ installed
- Composer installed
- Laravel project set up
-
Clone or copy this project into your Laravel project directory.
-
Install dependencies:
composer install- Run the Laravel bootstrap (first time setup):
php artisan migrate
php artisan config:cache- Ensure the
storage/logs/directory exists. Create it manually if it does not exist.
All classes and methods that can be executed must be explicitly registered.
The configuration for allowed jobs is located in:
/config/background-jobs.php
Example of the config structure:
<?php
return [
'retry_attempts' => 3, // Number of retry attempts
'retry_delay' => 5, // Delay in seconds between retries
'allowed_jobs' => [
App\Jobs\SampleJobClass::class => [
'process',
'handle',
],
],
];✅ Only classes and methods defined here can be run via CLI.
Create your job classes under any namespace (e.g., App\Jobs).
Example:
namespace App\Jobs;
class SampleJobClass
{
public function process($param1, $param2)
{
// Job logic here
}
public function handle()
{
// Another method
}
}- Each method you intend to run should be public.
- Make sure the class and methods are added to the
allowed_jobsconfig.
The main runner script is:
/run-job.php
It expects arguments in the following order:
php run-job.php [ClassName] [MethodName] [ParametersCommaSeparated]Run process method on SampleJobClass:
php run-job.php App\\Jobs\\SampleJobClass process param1,param2Note: Double backslashes
\\are needed to escape the namespace separator.
Run handle method without parameters:
php run-job.php App\\Jobs\\SampleJobClass handleYou can control retry behavior in:
/config/background-jobs.php
Edit these settings:
'retry_attempts' => 3, // Number of times to retry the job if it fails
'retry_delay' => 5, // Seconds to wait before retrying- If the job method throws an exception, it will automatically retry based on these settings.
The runner logs output to:
-
Successful execution logs:
/storage/logs/background_jobs.log -
Failure and exception logs:
/storage/logs/background_jobs_errors.log
| File | Purpose |
|---|---|
run-job.php |
Main runner script. Handles argument parsing, validation, execution, and retry. |
config/background-jobs.php |
Whitelist of allowed jobs and retry settings. |
storage/logs/ |
Directory for logging job execution results and errors. |
- Make sure to always register new job classes and methods in
background-jobs.php. - Jobs should be designed to be idempotent (safe to retry).
- You can modify or extend
run-job.phpif you want additional features like notifications, database job tracking, etc.
-
Class Discovery:
All PHP classes located inapp/Jobsare scanned. Each class's public methods (excluding constructors) are listed dynamically, along with their parameters. -
Job Dispatching:
Each method can be dispatched by clicking theDispatchbutton, which triggers a modal popup.
In the popup:
- You can enter job parameters dynamically (if required by the method).
- You can set job priority (higher number = higher priority).
- You can set a delay (in seconds) before the job executes.
-
Job Queue Table:
- All queued jobs are listed with their current statuses:
pending,running,completed,failed, orcancelled. - 5 jobs are shown per page for easy navigation (pagination).
- All queued jobs are listed with their current statuses:
- Select a class/method on the Dashboard.
- Fill in parameters, set priority and/or delay.
- Submit to queue the job.
- Job is stored in the
job_queuestable withpendingstatus. - Background runner is triggered using Symfony Process, starting a new background PHP process:
nohup php artisan job:run > /dev/null 2>&1 &
-
Continuously picks the next available pending job based on:
- Highest priority first.
- Then earliest scheduled
run_attime.
-
Processing Steps:
- Marks job as
running. - Dynamically instantiates the class and calls the method using PHP Reflection.
- Injects parameters from the stored JSON
payload. - On success, updates job as
completed. - On failure, updates job as
failedwith an error message.
- Marks job as
-
Cancellation Support:
If a job is marked asis_cancelled, it is skipped and marked ascancelled.
| Component | Purpose |
|---|---|
JobController@showAvailableJobs |
Lists all job classes and methods on the dashboard |
JobController@dispatchJob |
Queues a job with optional delay and priority |
JobController@startBackgroundJobRunner |
Launches a background job runner using Symfony Process |
JobController@getJobStatus |
Fetches status and retry count of a job via API |
JobController@cancel |
Cancels a running job |
RunJobs Command |
Background worker that processes jobs |
- Artisan Command:
app/Console/Commands/RunJobs.php
- Job Controller:
app/Http/Controllers/JobController.php
- Dashboard View:
resources/views/jobs/index.blade.php
- Database Table:
job_queue
- 🚀 Launch jobs dynamically with user-supplied parameters.
- ⏳ Delay job execution by X seconds.
- 🎯 Set priority for jobs.
- 📈 Real-time status tracking.
- 🔒 Job cancellation support.
- ⚙️ Symfony Process integration for non-blocking background execution.
- User selects
App\Jobs\SendEmail@sendWelcomeEmail. - Enters parameters like
userId,emailTemplateId. - Sets priority to 10 and delay to 60 seconds.
- Job is added to the queue, background worker starts.
- After 1 minute, the job runs, sends an email, and updates status to
completed.



