ProcessCallAPI.php 2.7 KB
<?php

namespace App\Jobs;

use App\Service\API\API;
use App\Service\Contract\APIRequest;
use App\Service\Handlers\AdsHandler;
use App\Service\HeaderLimits;
use App\Service\Limits;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;

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

    private $api;
    private $limitId;

    public $timeout = 1500;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(int $limitId, APIRequest $api)
    {
        $this->limitId = $limitId;
        $this->api = $api;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $limits = Limits::getInstance($this->api->getToken());

        try {
            $api = API::getInstance($this->api);
            //считаем на сколько объектов зарезервировано получение данных
            //только их и запрашиваем
            $limit = \App\Models\Limits::find($this->limitId);

            $limits = Limits::getInstance($this->api->getToken());

            $maxObjects = $limits->countObjectsLimit($this->api);

            if ($maxObjects and $maxObjects !== $limits::NAN && $this->api->getObjectsCount() > $maxObjects) {
                //те на которые не хватило баллов помещаем в очередь
                if ($apiR = $this->api->slice($maxObjects)) {
                    dispatch(new ProcessCallLimitedAPI($apiR))->onQueue('limits');
                }
            }
            $response = $api->execute();
            $limits->acceptRezerv($this->limitId, new HeaderLimits($response->headers()));

            //TODO: обработать результат.
            // если не хватило баллов на все что хотели запросить, то в очередь отправляем новый запрос на получение новых данных
            AdsHandler::getInstance($this->api)->handle($response);
        } catch (\Exception $e) {
            //TODO: надо отдельно выделить ошибки вызовов, за которые списываются баллы
            //https://yandex.ru/dev/direct/doc/dg/concepts/errors.html
            Log::debug($e);
            $limits->removeRezerv($this->limitId);
            throw $e;
        }
    }

    public function failed()
    {
        $this->api->failed();
    }

}