ProcessCallAPI.php 2.93 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 $tries = 1;
    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);

            $maxObjects = $limits::NAN;

            if ($limit->spent) {
                $limits = Limits::getInstance($this->api->getToken());

                $maxObjects = $limits->countObjectsLimitReserve($this->api, $limit);
            }

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

            $handler->handle($response);
        } catch (\Exception $e) {
            //TODO: надо отдельно выделить ошибки вызовов, за которые списываются баллы
            //https://yandex.ru/dev/direct/doc/dg/concepts/errors.html
            //Log::debug($this->api->getParams());
            Log::debug('');
            Log::debug("Exception in ProcessCallAPI, удаляем резервирование баллов. token_id {$this->api->getToken()->getKey()}, объектов {$this->api->getObjectsCount()} {$this->api->getService()} {$this->api->getMethod()}");
            $limits->removeRezerv($this->limitId);
            throw $e;
        }
    }

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

}