تعداد بازدید: 6806

Queue Job

سیستم پیاده سازی پردازش به صورت صف یا Queue System یک مفهوم عمومی در برنامه نویسی است که در لاراول نحوه پیاده سازی آن در Queue Backend های مختلف نظیر DataBase , Redis , … کاملا مشابه هم و پیکره بندی آن هم نزدیک به هم است.

Queue یک صف انتظار از پردازش ها (Job یا Listeners) برای اجرا می باشد. به گونه ای که پردازش ها در زمان اجرا به صف انتظار می روند و سرعت اجرای متد را کم نمی کنند و در Background برنامه اجرا می شوند.

چون در پشت برنامه Queue ها به اجرا در می آیند و تا حدودی از دید کاربر پنهان می شوند به آن ها Background Proccessing نیز می گوییم.

Queue Configuration

تنظیمات Queue مربوط به Queue Backend یا سرویس برپا کننده Queue و همچنین تنظیمات مربوط به هر سرویس در مسیر config/queue.php واقع شده است.

معمولا در هر Queue تعداد Jobs وجود دارد . این Jobs ها در زمان اجرا به دو دسته تقسیم می شوند.

  • FailedJobs : پروسه ها (Job) هایی که در زمان اجرا به خطا خورده باشند. این پروسه ها ذخیره و قابل پیگیری می باشند. در database QUEUE_CONNECTION جدولی با نام failed_jobs برای این مساله داریم.
  • Jobs : پروسه هایی که در صف انتظار برای اجرا می باشند. در database QUEUE_CONNECTION ما جدولی با نام jobs داریم.

QUEUE_CONNECTION یا سرویسی که ما قرار است از آن جهت پیاده سازی سیستم Queue استفاده کنیم می باشد که به پیرو آن سایر تنظیمات مانند FailedJobs و Jobs نیز انجام می شود.

برخی سرویس پیاده سازی Queue یا QUEUE_CONNECTION که در فایل queue.php به آن ها اشاره شده است:

  • sync : انجام همزمان پردازش ها . در این مورد عملا ما از تکنیک queue استفاده نمی کنیم و صرفا برای تست می باشد.
  • database :  استفاده از پایگاه داده.
  • beanstalkd
  • sqs
  • redis

هر queue connection می تواند queue attribute های مربوط به خود را داشته باشد.

Database Queue Connection

برای این که از database به عنوان queue connection استفاده کرد باید ابتدا در فایل .env مقدار QUEUE_CONNECTION  را برابر با database قرار دهید و بعد دستورات مربوط به ساخت migration و tables ها را اجرا کنید.

ساخت migration برای جدول jobs

php artisan queue:table

ساخت migration برای جدول failed_jobs

php artisan queue:failed-table

اجرای migration ها برای ساخت جداول

php artisan migrate

دستورات مربوط به پیکره بندی queue با پایگاه داده همین موارد است.

Jobs

تعریف پروسه و قرار دادن آن ها در صف انتظار (queue) . در این جا ما پروسه های زمان بر را در قالب job تعریف می کنیم و در جایی که به آن ها نیاز داشته باشیم از آن ها استفاده می کنیم.

به طور مثال ما میخواهیم به ازای برخی اعمال کاربر ایمیلی حاوی اطلاعات کاربر جاری به مدیر وب سایت بزنیم.این برخی اعمال کاربر یعنی مکان هایی که ما قرار است job را dispatch کنیم. این مکان ها در میان متد های controller می تواند باشد.

در ابتدا باید با دستور زیر job را بسازیم.

php artisan make:job LoggingUser

پس از اجرای دستور بالا فایل app/Jobs/LoggingUser.php ساخته می شود. حاوی یک کلاس شبیه به Listener ها که در آن متد handle وجود دارد که عملگر این job می باشد.

<?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;
use Illuminate\Support\Facades\Mail;
use App\Mail\Userinfo;
use App\User;
class LoggingUser implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    public $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }

    public function handle()
    {
        Mail::to(env('ADMIN_EMAIL'))->send(new UserInfo($this->user));
    }
}

job از قالب ShouldQueue پیاده سازی می شود. یعنی در Background Proccessing می باشد.

job هم پارامتر ورودی می گیرد. روال ورودی هم ساخت یک متغیر داخلی در کلاس و مقدار دهی آن در متد سازنده می باشد و همچنین در زمان dispatch کردن job می بایستی این پارامتر را به آن بدهیم.

dispatch Job

برای فراخوانی مستقیم Job باید آن را بوسیله کلاسش dispatch کنیم.این فراخوانی می تواند در هر کجای برنامه نظیر controller یا Route باشد.

در ادامه مثال قبل ما میخواهیم اگر کاربر endpoint برابر who را وارد کرد به ادمین اطلاعات کاربر ارسال بشه و در نهایت هم پیام به کاربر نمایش داده بشه.البته این عملیات منوط به لاگین بودن کاربر می باشد.

<?php
Route::get('who',function () {
    $user = Auth::user();
    if(isset($user))
    {
        \App\Jobs\LoggingUser::dispatch($user);
        return "hello {$user->name}";
    }
});

در مثال بالا Job چون در Background Proccessing انجام می شود سرعت closure ما را کم نمی کند . یعنی کاربر بلافاصله بعد از وارد کردن who مقدار خروجی را مشاهده می کند.

این روال در صورتی درست است که ما تنظیمات Queue را به درستی انجام داده باشیم و queue:work را Run کرده باشیم.

می تونید در controller هم job را فراخوانی کنید. ولی باید namespace آن را import کرده باشید. در مثال ما App\Jobs\LoggingUser می باشد.

Listen Queue

گوش دادن به queue یعنی وقتی ما سیستم Queue را پیاده سازی کردیم هر Job به صف Queue می رود و در آنجا که ما به آن Background می گوییم (عملا در مثال ما پایگاه داده و جدول job می باشد) منتظر برپایی می باشد.

جهت برپایی Queue باید دستور زیر را وارد کنید :

php artisan queue:work

پس از این هر Job که به queue اضافه بشه (به محل فراخوانی Job برسه) در پس زمینه اضافه شدن را لاگ می کنه و بعد اجراش می کنه.

نکته : در هاست های اشتراکی ما معمولا از QUEUE_CONNECTION از نوع پایگاه داده استفاده می کنیم. برای برپایی Queue هم از سیستم cron job استفاده می کنیم.

Event Listener – Queue Job

Event و Listenrs به عنوان یک مفهوم مشابه job عمل می کنند که تفاوت هایی در ساختارشون دارن :

Listener ها گوش به فرمان Event می باشند. یعنی در زمان fire شدن Event تمامی Listener های مربوط به آن Run می شوند و ما به صورت مستقیم قابلیت فراخوانی job ها را نداریم.

درسته که job و Listener هر دو قابلیت Background Proccessing را دارند اما Listener به ازای واقعه خاص می باشد اما job پردازشی است که صرفا به دلیل زمان بر بودن باید در پس زمینه اجرا شود.

پارامتر های لازم برای تمامی Listener ها در متد سازنده Event فراخوانی می شوند ولی پارامتر های مربوط به هر job در درون سازنده همان Job مقدار دهی می شوند.

 

اشتراک گذاری :

مدیر وب سایت گنوتک . برنامه نویسی رو با زبان C در هفده سالگی شروع کردم . در حال حاضر به برنامه نویسی php برپایه معماری MVC , HMVC و همچنین سیستم مدیریت محتوای WordPress و فریم ورک محبوب لاراول علاقه مند هستم و دوست دارم اطلاعاتم رو با شما به اشتراک بگذارم.

2 دیدگاه برای Queue Job

دیدگاهتان را بنویسید

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