پرش به محتوا

اجرای کارها با صف در لاراول

سلام دوستان. امروز میخوام در مورد یه موضوع خیلی کاربردی در لاراول صحبت کنم که در درجه اول خیلی مهم به نظر نمیرسه ولی ازش استفاده که میکنید میبینید چقد بدون صف زندگی کردن سخته. پس بذارید زود شروع کنم.

صف ها در برنامه نویسی به چه دردی میخورن؟

راستش صف ها جدا از اینکه توی زندگی ما آدم ها خیلی مهم هستن بعضی موقه ها توی کدهامون هم خیلی مهم میشن. مخصوصا اگه معلوم نباشه که هر کی چند دقیقه کارش طول میکشه. اگه بخوام یک مثال عملی بزنم فرض کنید یک تعداد خیلی زیادی کار دارید و میخواید اونها رو انجام بدید و از طرف دیگه مدت زمان انجام شدن هر کدوم از اونها از شروع تا پایان هم مشخص نیست. فرض کنید من یه موتور جستجو دارم که میخوام توی وبسایت ها بخزم و محتوای اونها رو ایندکس کنم و اگه ویدئو و عکسی هست پردازش کنم و ایندکس کنم. اگه محتوا متنی باشه خیلی زود و اگه عکس باشه بیشتر و ویدئو باشه خیلی بیشتر طول میکشه این عملیات تموم بشه. یه راه اینه که یه for بنویسم و بگم پشت سر هم این کارها رو انجام بده. ولی اگه توی ایتریشن دوم کدم به خطا خورد چی؟ اصلا از کجا بدونم به خطا خورده؟ اگه خواستم اجراهایی که به خطا خوردن رو دوباره اجرا کنم چی؟

صف ها در لاراول به شما این امکانات رو میدن که به راحتی جاب ها رو بذارید توی صف. اگه خطایی بوجود اومد لاگش رو ذخیره میکنن. میتونید با پکیج هاریزون مانیتور کنید که جابهاتون توی چه مرحله ای از اجرا قرار دارن چند بار به خطا خوردن و چند تا از جابها تموم شدن و خیلی چیزای دیگه که توی همین پست میبینیدشون.

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

استفاده از صف دیتابیس در لاراول

اولین کاری که باید بکنید اینه که جدول هاتون رو ایجاد کنید. برای اینکار توی محیط ترمینال لاراول و توی روت پروژه این دستورها رو ران کنید:

php artisan queue:table
php artisan queue:failed-table
php artisan migrate

با دستور اول یه مایگریشن ایجاد میشه برای ذخیره جاب های صف ها. با دستور دوم یه مایگریشن ایجاد میشه برای جابهایی که به خطا خوردن و با دستور سوم…

خب حالا بذارید یه جاب خیلی ساده بنویسیم. با دستور زیر میتونید یک جاب جدید درست کنید. جابها توی فولدر app/Jobs قرار میگیرن که اگه دستور زیر رو ران کنید فولدر خودش ساخته میشه.

php artisan make:job MyFirstJob

الان اگه فایل MyFirstJob.php رو باز کنید یچی مثل این میبینید:

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

class MyFristJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        //
    }
}

داخل متد handle این رو بنویسید:

$seconds = rand(0, 15);
sleep($seconds);
Log::info('job ran ' . Carbon::now()->toDateTimeString());

توی این قسمت گفتم که یک عدد تصادفی بین ۰ تا ۱۵ تولید کن و بعد به اندازه اون عدده ثانیه صبر کن و یه خروجی رو توی فایل لاگ بنویس و فرض کنید اون اسلیپ شدنه یه جاب سنگین مثل پردازش ویدیو و… هست. و یادتون نره که Carbon و Log رو use کنید.

گذاشتن جاب در صف

برای گذاشتن جاب توی صف در لاراول کافیه متد dispatch از اون جاب رو صدا بزنیم. برای مثال توی فایل routes/web.php قطعه کد زیر رو اضافه کنید:

Route::get('put', function () {
   \App\Jobs\MyFristJob::dispatch();
});

گفتم هر بار روت /put با متد get فراخوانی شد یدونه از این جاب رو بذار توی صف. پس کافیه روت /put رو get کنید. بعد از این کار باید توی جدول jobs یه رکورد ایجاد شده باشه. فیلد هایی که جدول jobs داره خیلی پیچیده نیستن و با یه نگاه میتونید ببینید که داره چه اتفاقی میفته.

صف های ایجاد شده در دیتابیس لاراول

تنظیمات درایور صف در لاراول

خب حالا نوبت این رسیده که صف رو توی پروژه ران کنیم. ولی قبلش یه سر به فایل config/queue.php بزنیم. اولین چیزی که احتمالا میبینید خط زیر هست:

'default' => env('QUEUE_CONNECTION', 'sync'),

این خط میگه که کانکشن پیشفرض من برای اجرای صف ها چی باشه که بصورت پیشفرض روی درایور sync تنظیم شده. درایور sync که یکم پایینتر هم اینجا و هم توی فایل کانفیگ میبینیدش میگه هر جابی که دیسپچ شد همون لحظه شروع بشه به ران شدن. در واقع اصلا صف حساب نمیشه.

'sync' => [
    'driver' => 'sync',
],

یسری کانشکن هم پایین تر از اون و اینسری فقط توی فایل کانفیگ میبینید 🙂 اونها کانکشن های مختلف به سیستم های مدیریت صف مختلف هستن. ما توی اینجا کانکشن پیشفرض رو تنظیمش میکنیم روی database و پایین تر در قسمت failed میتونید مشخص کنید که جابهایی که با خطا مواجه میشن کجا ذخیره بشن.

اجرای یک صف در لاراول

برای اجرای صف خیلی ساده دستور زیر رو اجرا کنید:

php artisan queue:work

این دستور شروع میکنه دونه دونه جابهایی که توی جدول jobs هستند رو اجرا میکنه. و بعد از تموم شدن جابهای صف، بازم منتظر میمونه که جاب جدید dispatch شه.

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

اگه فایل لاگتون رو چک کنید باید یچیزی مثل این رو ببینید که نشون میده هر جاب بعد از جاب قبلی اجرا شده.

خوشحال میشم اگه نکته ای هست کامنت کنید. موفق باشید.

3 دیدگاه دربارهٔ «اجرای کارها با صف در لاراول»

پاسخ دادن به علی مریمی لغو پاسخ

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *