Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 29.04.2021 21:09:10

Очереди для сотрудников(менеджеры) компаний

Всем привет! Я относительно не давно начал пользоваться очередями в Laravel. И вот одна из задач которую я не могу не как довести до конца.

Есть проект CRM. В ней такая структура, есть компании, а у компаний есть клиенты, заявки, товары, т.д. и т.п. Что-то вроде Market Place. И вот дали задание сделать очереди по принятию заявок для менеджеров. Что я имею ввиду, приходит заявка в какую-то компанию к примеру Company1, в этой компании к примеру есть 10 Mенеджеров, и нужно отправлять каждому по очереди заявки которые приходят в компанию. Так же, если зашла новая заявка и в очереди остаются 2 человека которые не взяли на протяжении 1 минуты заявку, очередь обнуляется и заявку могут взять все остальные 8 и те 2 человека. Такое я реализовал, но только в рамках одной компании.

И так есть контролер который принимает новые заявки и заносит их в очередь с приоритетом low.

class ApplicationController extends Controller
{
    public function create()
    {
         //logic которая заносит заявку в базу данных

         $job = ( new ApplicationJob($application, $user) )->onConnection('database');
         dispatch($job)
    }
}

Реализация самого Job который порождает другой Job PushNotification

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

    public $application;
    public $user;
    public $tries = 20;
    

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($application, $user)
    {
        $this->application = $application;
        $this->user = $user;
        $this->onQueue('low');
    }

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

        $queueHigh = DB::table('jobs')->where('queue', 'high')->exists();

        if ($queueHigh) {
            $this->release(15);
        } else {
            $job = ( new PushNotification($this->application, $this->user) )
                ->onConnection('database');

            dispatch($job);

            return;
        }
    }



    public function failed(Exception $exception)
    {
        Log::error(static::class . ' failed: ' . $exception->getMessage());
    }
}

В чем задача ApplicationJob. Он проверят есть ли в базе приоритет high (это Job PushNotification), если есть то удлиняет жизнь данную заявку на 15 секунд. Для чего это? Это нужно для того что б если пришла заявка в компанию, то уведомление для менеджеров будет прилетать им каждую минуту(если менеджеры не будут её брать к примеру на протяжении 5 минут), о том что новая заявка, нужно её взять и как только её возьмут, возьмётся следующая заявка из очереди если она есть.

Реализация самого Job PushNotification который отравляет каждую минуту WebPush для менеджеров если заявка до сих пор не принята

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


    public $application;
    public $user;
    public $companyId;
    public $tries = 20;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($application, $user)
    {
        $this->application = $application;
        $this->user = $user;
        $this->onQueue('high');
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        if ($this->attempts() === 1) { // первый раз отправляется WebPush
            $this->notification();
            $this->release(60);//удлиняется его жизнь на 60 секунд
        } else {
            
            if (если эта проверка сработает значит заявку не взяли) {
                $this->deleteCompanyJob();// обнуляем очередь
                $this->notification();// оправляем всем менеджерам 
                $this->release(60);// удлиняем на 60 секунд 
            }
        }
        
    }
}

в блоке else будем отправлять WebPush до тех пока не возьмут заявку

Подведём итоги! Именно такой жизненный цикл я вижу в отправки заявок по очереди менеджерам

Какие недостатки:

  1. Разумеется это проверка на приоритет high

  2. Такая система не работает по отдельным компаниям

Что значит не работает по отдельным компаниям, это значит что очередь может создаваться и в Company2, но пока не возьмут в Company2, WebPush не будет прилетать в Conpany1, иными словами создаётся очередь между компаниями на отправку WebPush.

  1. Кто вообще создавал такую логику с очередями?

  2. Как избавится от костыля на проверку приоритетности high? то есть выполнять приоритет low, пока в очереди не будет не одно high.

  3. Как сделать очередь для каждой компании отдельно?

P.S. Если я непонятно объяснил суть задачи, то напишите об этом, заранее спасибо за любую идею либо подсказку)

Не в сети

Подвал раздела