Your IP : 216.73.217.78


Current Path : /home/seto/indexator.pm/src/Search/
Upload File :
Current File : /home/seto/indexator.pm/src/Search/ConcurrentChecker.php

<?php

namespace App\Search;

class ConcurrentChecker
{
    /**
     * Run up to $concurrency queries in parallel via curl_multi.
     *
     * @param  array<int|string, string> $queries  map of key => query string
     * @return array<int|string, SearchResult>     same keys, SearchResult values
     */
    public function runBatch(
        SearchProviderInterface $provider,
        array $queries,
        int $concurrency = 10,
    ): array {
        if (empty($queries)) {
            return [];
        }

        $results  = [];
        $keys     = array_keys($queries);
        $chunks   = array_chunk($keys, $concurrency);

        foreach ($chunks as $chunk) {
            $mh      = curl_multi_init();
            $handles = [];

            foreach ($chunk as $key) {
                $ch   = curl_init();
                $opts = $provider->buildCurlOptions($queries[$key]);
                $opts[CURLOPT_RETURNTRANSFER] = true;
                curl_setopt_array($ch, $opts);
                curl_multi_add_handle($mh, $ch);
                $handles[$key] = $ch;
            }

            // Execute all handles concurrently
            $running = null;
            do {
                $status = curl_multi_exec($mh, $running);
                if ($running > 0) {
                    curl_multi_select($mh, 1.0);
                }
            } while ($running > 0 && $status === CURLM_OK);

            // Collect results
            foreach ($handles as $key => $ch) {
                $body     = (string) (curl_multi_getcontent($ch) ?? '');
                $httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
                $error    = curl_error($ch);

                if ($error !== '') {
                    $results[$key] = new SearchResult('error', 0, [], '', 'curl error: ' . $error);
                } else {
                    $results[$key] = $provider->parseResponse($body, $httpCode);
                }

                curl_multi_remove_handle($mh, $ch);
                curl_close($ch);
            }

            curl_multi_close($mh);
        }

        return $results;
    }
}