guzzle_retry_middleware icon indicating copy to clipboard operation
guzzle_retry_middleware copied to clipboard

Symfony 6.3 update issue

Open constantinosergiou opened this issue 1 year ago • 4 comments

In proxy-classes.php line 165 ContainerST20YFb\GuzzleRetryMiddlewareProxyBeca8c9::__invoke(): Argument 1 ($request) must be of type Psr\Http\Message\RequestInterface, Closure given, called in C:\api\vendor\guzzlehttp\guzzle \src\HandlerStack.php on line 203 @caseyamcl

composer.json ->

      "php": "^8.2",
      "ext-ctype": "*",
      "ext-iconv": "*",
      "ext-json": "*",
      "ext-libxml": "*",
      "ext-ssh2": "*",
      "caseyamcl/guzzle_retry_middleware": "^2.7",
      "composer/package-versions-deprecated": "1.11.99.4",
      "doctrine/annotations": "^1.13",
      "doctrine/cache": "^1.10",
      "doctrine/doctrine-bundle": "^2.0",
      "doctrine/doctrine-migrations-bundle": "^3",
      "doctrine/orm": "^2",
      "egulias/email-validator": "^3.2",
      "friendsofsymfony/rest-bundle": "^3.4",
      "gmponos/guzzle_logger": "^2.2",
      "google/cloud-bigquery": "^1.23",
      "gree/jose": "^2.2",
      "guzzlehttp/guzzle": "^6.5",
      "league/flysystem-bundle": "^2.2",
      "league/flysystem-sftp": "^3.0",
      "maxbanton/cwh": "^2.0",
      "nelmio/api-doc-bundle": "^4.8",
      "ocramius/package-versions": "^2.5",
      "sensio/framework-extra-bundle": "^6.2",
      "symfony-bundles/redis-bundle": "^3.1.0",
      "symfony/cache": "6.3",
      "symfony/console":"6.3",
      "symfony/dotenv": "6.3",
      "symfony/expression-language":"6.3",
      "symfony/finder": "6.3",
      "symfony/flex": "^1.9.10",
      "symfony/framework-bundle": "6.3",
      "symfony/intl": "6.3",
      "symfony/monolog-bundle": "^3.7",
      "symfony/routing": "6.3",
      "symfony/security-bundle": "6.3",
      "symfony/security-csrf": "6.3",
      "symfony/serializer": "6.3",
      "symfony/validator": "6.3",
      "symfony/yaml": "6.3"
  },```

constantinosergiou avatar Sep 21 '23 18:09 constantinosergiou

Hi, @constantinosergiou, can you provide some sample code from your use case? I'm having trouble replicating this issue. This library doesn't interact with the symfony libraries, so I'm a bit perplexed.

caseyamcl avatar Sep 28 '23 20:09 caseyamcl

is command job that has a handler and i have this service.yaml

    retry_middleware:
        lazy: true
        class: GuzzleRetry\GuzzleRetryMiddleware
        factory: [ GuzzleRetry\GuzzleRetryMiddleware, factory ]

    logger_middleware:
        lazy: true
        class: GuzzleLogMiddleware\LogMiddleware
        arguments:
            $handler: '@App\Handler\RequestLogHandler'

    retryable_handler:
        lazy: true
        class: GuzzleHttp\HandlerStack
        factory: [ GuzzleHttp\HandlerStack, create ]
        calls:
            - push: [ '@logger_middleware' ]
            - push: [ '@retry_middleware' ]

    client:
        lazy: true
        class: GuzzleHttp\Client
        arguments:
            $config:
                timeout: 10
                handler: '@retryable_handler'
                base_uri: '%env(URL)%'
                auth:
                    - '%env(USER)%'
                    - '%env(Password)%'
                headers:
                    Content-Type: 'application/json'

and on command script ->

   <?php

  private function sendData(array $data): array
    {
        return $this->jobHandler(function () use ($data) {
            $res = $this->Client->post('/api/v2/users/whatever.json', [
                'body' => json_encode(['users' => array_values($data)]),
            ]);
            $responseStatus = $res->getStatusCode();
            $this->logger->debug(
                sprintf(
                    'Data response code %s',
                    $responseStatus
                )
            );

            return $res;
        }, true);
    }



     /**
     * Retry batch job requests.
     *
     * @throws Exception|GuzzleException
     */
    private function JobHandler(callable $callable, bool $checkCompleted = false): ?array
    {
        $count = 0;
        /** @var Response $response */
        $response = null;

        while (true) {
            try {
                $response = $callable();
                break;
            } catch (BadResponseException $e) {
                $this->logger->debug('Bad  request', [
                    'exception' => $e,
                ]);
                $data = json_decode($e->getResponse()->getBody()->getContents(), true);

               
                if ('TooManyJobs' == $data['error'] ?? '') {
                    if (5 == $count) {
                        throw new Exception('Retry limit reached!', 0, $e);
                    }

                    ++$count;
                } else {
                    throw $e;
                }
            }
        }

        if ($checkCompleted) {
            $job = json_decode($response->getBody()->getContents(), true);
            $this->logger->debug('Checking if job is finished!', [
                'job_id' => $job['job_status']['id'],
            ]);
            $uri = sprintf('/api/v2/job_statuses/%s.json', $job['job_status']['id']);

            while (true) {
                sleep(5);
                $jobStatusResponse = $this->Client->get($uri);
                $jobStatus = json_decode($jobStatusResponse->getBody()->getContents(), true);

                switch ($jobStatus['job_status']['status']) {
                    case 'failed':
                    case 'killed':
                        throw new Exception(sprintf('job (%s) failed', $job['job_status']['id']));
                    case 'completed':
                        return $jobStatus;
                }
            }
        }

        return null;
    }

    ?>
and this is the RequestLogHandler 
    <?php

namespace App\Handler;

use GuzzleHttp\TransferStats;
use GuzzleLogMiddleware\Handler\HandlerInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Log\LoggerInterface;
use Throwable;

class RequestLogHandler implements HandlerInterface
{
    public function log(
        LoggerInterface $logger,
        RequestInterface &$request,
        ?ResponseInterface $response = null,
        ?Throwable $exception = null,
        ?TransferStats $stats = null,
        array $options = []
    ): void {
        if ($response) {
            $logger->debug('limits', [
                'X-Rate-Limit' => $response->getHeader('X-Rate-Limit'),
                'X-Rate-Limit-Remaining' => $response->getHeader('X-Rate-Limit-Remaining'),
            ]);
        }
    }
}
?>

constantinosergiou avatar Sep 30 '23 10:09 constantinosergiou

Hi, @constantinosergiou, can you provide some sample code from your use case? I'm having trouble replicating this issue. This library doesn't interact with the symfony libraries, so I'm a bit perplexed.

i added the code could you check @caseyamcl

constantinosergiou avatar Oct 07 '23 04:10 constantinosergiou

Hi, @constantinosergiou, can you provide some sample code from your use case? I'm having trouble replicating this issue. This library doesn't interact with the symfony libraries, so I'm a bit perplexed.

i added the code could you check @caseyamcl

any updates?

constantinosergiou avatar Dec 30 '23 11:12 constantinosergiou