Queue: jobs & schedule
Asynchronous tasks
Laravel queue docs: https://laravel.com/docs/master/queues
Jobs
In this guide, the queue driver will be database, you have to config your application to use database.
php artisan queue:table
QUEUE_CONNECTION=database
php artisan migrate
Usage
Create a new Job
php artisan make:job ProcessHeavyServerTask
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Log;
class ProcessHeavyServerTask implements ShouldQueue
{
use Dispatchable;
use InteractsWithQueue;
use Queueable;
use SerializesModels;
/**
* Create a new job instance.
*/
public function __construct(
public mixed $param,
public mixed $param_alt,
) {
}
/**
* Execute the job.
*/
public function handle()
{
// Very heavy server task...
Log::debug('Success on job '.now());
}
public function failed(\Throwable $exception)
{
Log::error('Error on job');
}
}
Call job
<?php
class MainController extends Controller
{
public function index()
{
$param = [];
$param_alt = true;
ProcessHeavyServerTask::dispatch($param, $param_alt);
}
}
Execute
If you change anything into your job, you have to re-run the command. And for EVERY deployment, you have to restart supervisor
.
Local
php artisan queue:work --queue
Server
Install supervisor
.
TIP
Replace app-name
with the name of your application.
sudo apt install supervisor -y
cd /etc/supervisor/conf.d
sudo vim /etc/supervisor/conf.d/app-name-worker.conf
[program:app-name-worker]
process_name=%(program_name)s
command=php8.2 /var/www/app-name/artisan queue:work database --sleep=3 --tries=3
autostart=true
autorestart=true
user=nginx
numprocs=1
redirect_stderr=true
stdout_logfile=/var/www/app-name/storage/logs/worker.log
stopwaitsecs=3600
In /etc/supervisor/supervisord.conf
, check if this exist.
[include]
files = /etc/supervisor/conf.d/*.conf
When you create a new config, use these commands.
sudo supervisorctl reread
sudo supervisorctl update
INFO
Manage restart without sudo
To restart supervisor from CI, you have to allow restart without sudo
.
sudo vim /etc/supervisor/supervisord.conf
Replace USER
with your username.
[unix_http_server]
chown = USER:nginx
Restart supervisor.
sudo service supervisor restart
Now USER
can restart supervisor without sudo
.
supervisorctl start app-name-worker
When you deploy a new app version, restart supervisor worker with this command.
supervisorctl restart app-name-worker
Example with bookshelves
app.
supervisorctl start bookshelves-worker
List all workers
supervisorctl
Example of output.
app-name-worker RUNNING pid 40598, uptime 0:03:30
Restart it.
supervisorctl start app-name-worker
Add it to CI
Add to your CI config or post-merge
Git hook.
deploy-job:
stage: deploy
script:
- supervisorctl restart app-name-worker
only:
- main
Schedule
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use App\Console\Commands\AnyCommand;
class Kernel extends ConsoleKernel
{
protected function schedule(Schedule $schedule)
{
$schedule->command(AnyCommand::class, ['argument', '--option'])->daily();
}
}
Shell commands
protected function schedule(Schedule $schedule)
{
$schedule->exec('node /home/forge/script.js')->daily();
}
Cheatsheet
List schedule
php artisan schedule:list
Run schedule
php artisan schedule:run
Keep schedule running
php artisan schedule:work
Run in production
Set php
version into cron with php8.1
. Just use crontab
.
crontab -e
* * * * * cd /path/to/project && php8.1 artisan schedule:run >> /dev/null 2>&1