skip to Main Content

Ok so I am a little stuck with this issue. I have a foreach loop (usually 50 results) that queries an API using Guzzle via Laravel Http and I am getting really inconsistent results.

I monitor the inserts in the database as they come in and sometimes the process seems slow and other times the process will fail with the following after x number of returned results.

cURL error 6: Could not resolve host: api.coingecko.com

The following is the actual code im using to fetch the results.

foreach ($json_result as $account) {

                    var_dump($account['name']);

                    $name = $account['name'];
                    $coingecko_id = $account['id'];
                    $identifier = strtoupper($account['symbol']);

                    $response_2 = Http::get('https://api.coingecko.com/api/v3/coins/'.urlencode($coingecko_id).'?localization=false');

                    if($response_2->successful()){

                        $json_result_extra_details = $response_2->json();

                        if( isset($json_result_extra_details['description']['en']) ){
                            $description = $json_result_extra_details['description']['en'];
                        }

                        if( isset($json_result_extra_details['links']['twitter_screen_name']) ){
                            $twitter_screen_name = $json_result_extra_details['links']['twitter_screen_name'];
                        }
                        
                    }else {
                        // Throw an exception if a client or server error occurred...
                        $response_2->throw();
                    }

                    $crypto_account = CryptoAccount::updateOrCreate(
                        [
                            'identifier' => $identifier
                        ],
                        [
                            'name' => $name,
                            'identifier' => $identifier,
                            'type' => "cryptocurrency",
                            'coingecko_id' => $coingecko_id,
                            'description' => $description,
                        ]);

                    //sleep(1);
    
                }

Now I know I am within the API rate limit of 100 calls a minute so I don’t think that is the issue. I am wondering if this is a server/api issue which I don’t really have any control over or if it related to my code and how Guzzle is implemented.

When I do single queries I don’t seem to have a problem, the issue seems to be when it is inside the foreach loop.

Any advice would be great. Thanks

EDIT

Ok to update the question, I am now wondering if this is Guzzle/Laravel related. I changed the API to now point to the Twitter API and I am getting the same error after 80 synchronous requests.

2

Answers


  1. I think it’s better to use Asynchronous Request directly with Guzzle.

    $request = new GuzzleHttpPsr7Request('GET', 'https://api.coingecko.com/api/v3/coins?localization=false');
    
    for ($i=0; $i < 50 ; $i++) {
        $promise = $client->sendAsync($request)
            ->then(function ($response) {
                echo 'I completed! ' . $response->getBody();
            });
        $promise->wait();
    }
    

    more information on Async requests: Doc

    Login or Signup to reply.
  2. I have a similar problem as yours.

    I doing the HTTP requests in the loop, and the first 80 requests are okay.
    But the 81st start throwing this "Could not resolve host" exception.
    It’s very strange for me because the domain can be resolved perfectly fine on my machine.

    Thus I start digging into the code.
    End up I found that Laravel’s Http facades keep generate the new client.
    And I guess this eventually trigger the DNS resolver’s rate limit?

    So I have the workaround as following:

    // not working
    // as this way will cause Laravel keep getting a new HTTP client from guzzle.
    foreach($rows as $row) {
        $response = Http::post();
    }
    
    // workaround
    $client = new GuzzleHttpClient();
    foreach($rows as $row) {
        $response = $client->post();
        // don't forget use $response->getBody();
    }
    

    i believe it’s because $client will cached the DNS resolve result, thus it will reduce the call to DNS resolver and not trigger the rate limit?
    I’m not sure whether it was right. BUT it’s working for me.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search