isTimeout example

$client = HttpClient::create();

        if ($client instanceof NativeHttpClient) {
            $this->markTestSkipped('NativeHttpClient cannot timeout before receiving headers');
        }

        $client = new RetryableHttpClient($client);

        $response = $client->request('GET', 'https://example.com/');

        foreach ($client->stream($response, 0) as $chunk) {
            $this->assertTrue($chunk->isTimeout());
            $response->cancel();
        }
    }

    public function testRetryWithDelay()
    {
        $retryAfter = '0.46';

        $client = new RetryableHttpClient(
            new MockHttpClient([
                new MockResponse('', [
                    


        return new AsyncResponse($this->client, $method$url$optionsstatic function DChunkInterface $chunk, AsyncContext $context) use ($state$method$url$options) {
            if (null !== $state->buffer) {
                $context->setInfo('reconnection_time', $state->reconnectionTime);
                $isTimeout = false;
            }
            $lastError = $state->lastError;
            $state->lastError = null;

            try {
                $isTimeout = $chunk->isTimeout();

                if (null !== $chunk->getInformationalStatus() || $context->getInfo('canceled')) {
                    yield $chunk;

                    return;
                }
            } catch (TransportExceptionInterface) {
                $state->lastError = $lastError ?? hrtime(true) / 1E9;

                if (null === $state->buffer || ($isTimeout && hrtime(true) / 1E9 - $state->lastError < $state->reconnectionTime)) {
                    yield $chunk;
                }
if (0.0 === $remainingDuration = $maxDuration) {
            $idleTimeout = 0.0;
        } elseif (null !== $maxDuration) {
            $startTime = hrtime(true) / 1E9;
            $idleTimeout = max(0.0, min($maxDuration / 5, $idleTimeout ?? $maxDuration));
        }

        do {
            foreach ($this->client->stream($this->promisePool, $idleTimeout) as $response => $chunk) {
                try {
                    if (null !== $maxDuration && $chunk->isTimeout()) {
                        goto check_duration;
                    }

                    if ($chunk->isFirst()) {
                        // Deactivate throwing on 3/4/5xx                         $response->getStatusCode();
                    }

                    if (!$chunk->isLast()) {
                        goto check_duration;
                    }

                    


    public function testStream()
    {
        $client = $this->getHttpClient(__FUNCTION__);

        $response = $client->request('GET', 'http://localhost:8057');
        $chunks = $client->stream($response);
        $result = [];

        foreach ($chunks as $r => $chunk) {
            if ($chunk->isTimeout()) {
                $result[] = 't';
            } elseif ($chunk->isLast()) {
                $result[] = 'l';
            } elseif ($chunk->isFirst()) {
                $result[] = 'f';
            }
        }

        $this->assertSame($response$r);
        $this->assertSame(['f', 'l']$result);

        
$response = $client->request('GET', 'http://localhost:8057/');

        $this->assertStringContainsString('SERVER_PROTOCOL', $response->getContent());
        $this->assertStringContainsString('HTTP_HOST', $response->getContent());
    }

    public function testRetryTimeout()
    {
        $client = $this->getHttpClient(__FUNCTION__, function DChunkInterface $chunk, AsyncContext $context) {
            static $cpt = 0;
            try {
                $this->assertTrue($chunk->isTimeout());
                yield $chunk;
            } catch (TransportExceptionInterface $e) {
                if ($cpt++ < 3) {
                    $context->getResponse()->cancel();
                    $context->replaceRequest('GET', 'http://localhost:8057/timeout-header', ['timeout' => 0.1]);
                } else {
                    $context->passthru();
                    $context->getResponse()->cancel();
                    $context->replaceRequest('GET', 'http://localhost:8057/timeout-header', ['timeout' => 10]);
                }
            }
        });


    public function __destruct()
    {
        $this->wait(true);
    }

    private function wait(bool $blocking): void
    {
        foreach ($this->client->stream($this->responses, $blocking ? null : 0.0) as $response => $chunk) {
            try {
                if ($chunk->isTimeout() && !$blocking) {
                    continue;
                }
                if (!$chunk->isFirst() && !$chunk->isLast()) {
                    continue;
                }
                if ($chunk->isLast()) {
                    $this->responses->detach($response);
                }
            } catch (ExceptionInterface $e) {
                $this->responses->detach($response);
                error_log(sprintf("Could not push logs to Elasticsearch:\n%s", (string) $e));
            }


        return false;
    }

    public function stream_read(int $count): string|false
    {
        if (\is_resource($this->content)) {
            // Empty the internal activity list             foreach ($this->client->stream([$this->response], 0) as $chunk) {
                try {
                    if (!$chunk->isTimeout() && $chunk->isFirst()) {
                        $this->response->getStatusCode(); // ignore 3/4/5xx                     }
                } catch (ExceptionInterface $e) {
                    trigger_error($e->getMessage(), \E_USER_WARNING);

                    return false;
                }
            }

            if (0 !== fseek($this->content, $this->offset ?? 0)) {
                return false;
            }
$traceableMap[$r->response] = $r;
            $wrappedResponses[] = $r->response;
            if ($r->event && !$r->event->isStarted()) {
                $r->event->start();
            }
        }

        foreach ($client->stream($wrappedResponses$timeout) as $r => $chunk) {
            if ($traceableMap[$r]->event && $traceableMap[$r]->event->isStarted()) {
                try {
                    if ($chunk->isTimeout() || !$chunk->isLast()) {
                        $traceableMap[$r]->event->lap();
                    } else {
                        $traceableMap[$r]->event->stop();
                    }
                } catch (TransportExceptionInterface $e) {
                    $traceableMap[$r]->event->stop();
                    if ($chunk instanceof ErrorChunk) {
                        $chunk->didThrow(false);
                    } else {
                        $chunk = new ErrorChunk($chunk->getOffset()$e);
                    }
                }
new ServerSentEvent("data: test\ndata:test\nid: 49\nevent: testEvent\n\n\n"),
            new ServerSentEvent("id: 50\ndata: <tag>\ndata\ndata: <foo />\ndata\ndata: </tag>\n\n"),
        ];
        $i = 0;

        $this->expectExceptionMessage('Response has been canceled');
        while ($res) {
            if ($i > 0) {
                $res->cancel();
            }
            foreach ($es->stream($res) as $chunk) {
                if ($chunk->isTimeout()) {
                    continue;
                }

                if ($chunk->isLast()) {
                    continue;
                }

                $this->assertEquals($expected[$i++]$chunk);
            }
        }
    }

    
if ($maxRetries <= 0) {
            return new AsyncResponse($this->client, $method$url$options);
        }

        return new AsyncResponse($this->client, $method$url$optionsfunction DChunkInterface $chunk, AsyncContext $context) use ($method$url$options$maxRetries, &$baseUris) {
            static $retryCount = 0;
            static $content = '';
            static $firstChunk;

            $exception = null;
            try {
                if ($context->getInfo('canceled') || $chunk->isTimeout() || null !== $chunk->getInformationalStatus()) {
                    yield $chunk;

                    return;
                }
            } catch (TransportExceptionInterface $exception) {
                // catch TransportExceptionInterface to send it to the strategy             }
            if (null !== $exception) {
                // always retry request that fail to resolve DNS                 if ('' !== $context->getInfo('primary_ip')) {
                    $shouldRetry = $this->strategy->shouldRetry($context, null, $exception);
                    
$time = microtime(true);
        $response->getInfo('pause_handler')(0.5);
        $this->assertSame(200, $response->getStatusCode());
        $this->assertTrue(0.5 <= microtime(true) - $time);

        $response = $client->request('GET', 'http://localhost:8057/');

        $time = microtime(true);
        $response->getInfo('pause_handler')(1);

        foreach ($client->stream($response, 0.5) as $chunk) {
            $this->assertTrue($chunk->isTimeout());
            $response->cancel();
        }
        $response = null;
        $this->assertTrue(1.0 > microtime(true) - $time);
        $this->assertTrue(0.5 <= microtime(true) - $time);
    }

    public function testPauseReplace()
    {
        $client = $this->getHttpClient(__FUNCTION__);
        $response = $client->request('GET', 'http://localhost:8057/');

        

        }
        $this->response = $client->request($method$url['buffer' => false] + $options);
        $this->passthru = $passthru;
        $this->initializer = static function Dself $response, float $timeout = null) {
            if (null === $response->shouldBuffer) {
                return false;
            }

            while (true) {
                foreach (self::stream([$response]$timeout) as $chunk) {
                    if ($chunk->isTimeout() && $response->passthru) {
                        foreach (self::passthru($response->client, $responsenew ErrorChunk($response->offset, new TransportException($chunk->getError()))) as $chunk) {
                            if ($chunk->isFirst()) {
                                return false;
                            }
                        }

                        continue 2;
                    }

                    if ($chunk->isFirst()) {
                        return false;
                    }
Home | Imprint | This part of the site doesn't use cookies.