Skip to content

Conversation

@WendellAdriel
Copy link
Contributor

@WendellAdriel WendellAdriel commented Oct 27, 2025

This PR adds the ability to control how many concurrent HTTP requests the Http::pool and Http::batch can make.

Http::pool Example

A new optional param should be passed in the Http::pool call:

$responses = Http::pool(fn (Pool $pool) => [
    $pool->get('http://localhost/first'),
    $pool->get('http://localhost/second'),
    $pool->get('http://localhost/third'),
], 2); // Sets the pool to have at max 2 concurrent HTTP requests

Http::batch Example

A new ->concurrency() method can be called before calling the ->send() or ->defer() methods:

$responses = Http::batch(fn (Batch $batch) => [
    $batch->as('first')->get('http://localhost/first'),
    $batch->as('second')->get('http://localhost/second'),
    $batch->as('third')->get('http://localhost/third'),
])->concurrency(2)->send(); // Sets the batch to have at max 2 concurrent HTTP requests

@taylorotwell taylorotwell merged commit f5cf0d4 into laravel:12.x Oct 28, 2025
66 checks passed
@taylorotwell
Copy link
Member

Nice - thanks!

@jonnywilliamson
Copy link
Contributor

jonnywilliamson commented Nov 28, 2025

@WendellAdriel Should the ->retry method work in this example:

$responses = Http::batch(fn (Batch $batch) => [
    $batch->as('first')->retry(3)->get('http://localhost/first'),
    $batch->as('second')->get('http://localhost/second'),
    $batch->as('third')->get('http://localhost/third'),
])->concurrency(2)->send();

I might be doing something wrong but I can't get it to retry.

@WendellAdriel
Copy link
Contributor Author

@jonnywilliamson this weekend I'm busy, but next week I'll check it ASAP to give you some feedback.

@jonnywilliamson
Copy link
Contributor

Actually I think I found a way to test it properly! Thank you for replying.

@WendellAdriel
Copy link
Contributor Author

@jonnywilliamson did you check if the retry is working as expected?

@jonnywilliamson
Copy link
Contributor

jonnywilliamson commented Dec 3, 2025

Yes this proves it works!

<?php

use Illuminate\Http\Client\Batch;
use Illuminate\Support\Facades\Http;

it('retries failing requests within a batch while concurrent', function () {
    // 1. Strict Mode: Ensure only faked requests are allowed
    Http::preventStrayRequests();

    // 2. Setup Fakes
    Http::fake([
        // The 'first' URL will fail twice (500), then succeed (200)
        'http://localhost/first' => Http::sequence()
            ->push('Server Error 1', 500)
            ->push('Server Error 2', 500)
            ->push('First Success', 200),

        // All other URLs return a standard 200 OK
        'http://localhost/*' => Http::response('OK', 200),
    ]);

    // 3. Execute Batch
    $responses = Http::batch(fn (Batch $batch) => [
        $batch->as('first')->retry(3)->get('http://localhost/first'),
        $batch->as('second')->get('http://localhost/second'),
        $batch->as('third')->get('http://localhost/third'),
        $batch->as('fourth')->get('http://localhost/forth'),
        $batch->as('fifth')->get('http://localhost/fifth'),
    ])->concurrency(2)->send();

    // 4. Assertions

    // Verify 'first' eventually succeeded and got the correct final response
    expect($responses['first']->successful())->toBeTrue();
    expect($responses['first']->body())->toBe('First Success');

    // Verify all other requests succeeded
    expect($responses['second']->successful())->toBeTrue();
    expect($responses['third']->successful())->toBeTrue();
    expect($responses['fourth']->successful())->toBeTrue();
    expect($responses['fifth']->successful())->toBeTrue();

    // CRITICAL ASSERTION:
    // We expect 7 total requests sent to the "network":
    // - 3 attempts for 'first' (Fail, Fail, Success)
    // - 1 attempt for 'second'
    // - 1 attempt for 'third'
    // - 1 attempt for 'fourth'
    // - 1 attempt for 'fifth'
    // = 7 total
    Http::assertSentCount(7);
});

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants