صف های لاراولی

صف های لاراولی
صف های لاراولی


بیشتر وقت‌ها توی پروژه‌هامون یک سری کار داریم که باید توی پس‌زمینه سایت اجرا بشه یا از کاربران زمان زیادی رو می‌گیره برای همین لاراول صف هارو ارائه داده که میتونیم ازش استفاده کنیم. توی این آموزش نحوه‌ی استفاده از job و ‌queue رو قراره با هم یاد بگیریم.

قبل از هرکاری توی فایل .env

QUEUE_CONNECTION=sync

رو به

QUEUE_CONNECTION=database

تغییر بدید، البته از کانکشن های دیگه ای هم میتوانید استفاده کنید ولی من توی این آموزش فقط database رو آموزش میدم. وقتی از database استفاده می‌کنید قطعا به یک جدول هم نیاز دارید

php artisan queue:table
php artisan migrate

همه صف هایی که ساخته میشن به صورت پیشفرض توی مسیر app/Jobs ساخته میشن، نگران نباشید اگه هنوز نتونستید پیداش کنید کافیه دستور ‍‍‍‍php artisan make:job ProcessPodcast رو اجرا کنید، یادتون نره اسمشو عوض کنید ها... قبل از هرکاری بذارید با ساختار job آشنا بشیم

<?php
namespace App\Jobs;
use App\Models\Podcast;
use App\Services\AudioProcessor;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class ProcessPodcast implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* The podcast instance.
*
* @var \App\Models\Podcast
*/
protected $podcast;
/**
* Create a new job instance.
*
* @param App\Models\Podcast $podcast
* @return void
*/
public function __construct(Podcast $podcast)
{
$this->podcast = $podcast;
}
/**
* Execute the job.
*
* @param App\Services\AudioProcessor $processor
* @return void
*/
public function handle(AudioProcessor $processor)
{
// Process uploaded podcast...
}
}

خب همینطور که می‌بینید دوتا تابع داریم به اسم های __construct وhandle. زمانی که یک صف شروع به کار می‌کنه تابع handle صدا زده میشه از تابع __construct هم برای ارسال اطلاعات به job استفاده می‌کنیم. توی این مثال مدل رو به صورت مستقیم به jobارسال کردیم با بهره‌گیری از SerializesModels که توی Job استفاده شده.

وقتی که مدل رو به job ارسال می‌کنید فقط شناسه اون مدل ارسال میشه که باعث میشه داده کمتری توی دیتابیس ذخیره‌ بشه و زمانی که صف اجرا میشه داده تازه‌تری بارگذاری میشه.

لاراول توی job ها هم ازmiddlewareبهره برده که میتونید باهاش از اجرای چند باره یک صف جلوگیری کنید، فقط کافیه متدmiddleware` رو توی job بسازید و اون یک آرایه برگردونید.

use Illuminate\Queue\Middleware\WithoutOverlapping;
/**
* Get the middleware the job should pass through.
*
* @return array
*/
public function middleware()
{
return [new WithoutOverlapping($this->user->id)];
}

خب هر صفی بالاخره باید دوباره برگرده به لیست که اگر میخواید تأخیری این وسط اعمال کنید باید releaseAfter اضافه کنید.

/**
* Get the middleware the job should pass through.
*
* @return array
*/
public function middleware()
{
return [(new WithoutOverlapping($this->order->id))->releaseAfter(۶۰)];
}

اگر هم می‌خواید به سرعت برگرده توی صف می‌تونید dontRelease استفاده کنید.

/**
* Get the middleware the job should pass through.
*
* @return array
*/
public function middleware()
{
return [(new WithoutOverlapping($this->order->id))->dontRelease()];
}

اگر توی حالت های بالا خطایی رخ بده job دوباره به صف برنمی‌گرده به اصطلاح release نمیشه که باید از expireAfter استفاده کنید که بعد مدت زمان خاصی دوباره صف اجرا بشه.

/**
* Get the middleware the job should pass through.
*
* @return array
*/
public function middleware()
{
return [(new WithoutOverlapping($this->order->id))->expireAfter(۱۸۰)];
}

حالا که job رو ساختیم وقتشه ازش استفاده کنیم، برای این کار باید job رو dispatch کنیم.

public function store(Request $request)
{
$podcast = Podcast::create(...);
// ...
ProcessPodcast::dispatch($podcast);
}

ورودی dispatch به constructor ارسال میشه. اگر بخواید برای dispatch کردن job شرطی داشته باشید می توانید از کد های زیر استفاده کنید.

ProcessPodcast::dispatchIf($accountActive, $podcast);
ProcessPodcast::dispatchUnless($accountSuspended, $podcast);

اگر نیاز دارید که توی اجرای job هاتون تاخیری ایجاد کنید باید از زیر استفاده کنید که ۱۰ دقیقه دیرتر job شروع به کار می‌کنه.

ProcessPodcast::dispatch($podcast)->delay(now()->addMinutes(۱۰));

بعضی وقت ها نیاز دارید صفی که ساخته میشه به سرعت پردازش بشه که از dispatchSync استفاده می‌کنیم که در واقع هیچ صفی ساخته نمیشه و تابع handle توی job به صورت مستقیم صدا زده میشه.

ProcessPodcast::dispatchSync($podcast);`

امیدوارم آموزش مفیدی بوده باشه!


https://rp76.ir/blog/post/%D8%B5%D9%81-%D9%87%D8%A7%DB%8C-%D9%84%D8%A7%D8%B1%D8%A7%D9%88%D9%84%DB%8C