ProcessCallAPI.php 3.09 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
     * @throws \Throwable
     */
    public function handle()
    {
        $this->api->getToken()->refresh();

        $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) {
                $maxObjects = $limits->countObjectsLimitReserve($this->api, $limit);
            }

            if (
                ($maxObjects && $maxObjects !== $limits::NAN && $this->api->getObjectsCount() > $maxObjects)
            ||
                (($maxObjects = $this->api->getMaxCount()) && $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) {

            Log::debug('');
            Log::debug("Exception in ProcessCallAPI, удаляем резервирование баллов. token_id {$this->api->getToken()->getKey()}, объектов {$this->api->getObjectsCount()} {$this->api->getService()} {$this->api->getMethod()}");

            if (isset($response)) {
                $headerLimit = new HeaderLimits($response->headers());
            }

            try {
                $limits->removeRezerv($this->limitId, $headerLimit ?? null);
            } catch (\Throwable $e) {
                Log::error($e);
            }

            throw $e;
        }
    }

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

}