feat: add retry client trait for api requests
feat: add retry client trait for api requests
This commit is contained in:
		
							parent
							
								
									d7ff806129
								
							
						
					
					
						commit
						7eac908bc4
					
				
							
								
								
									
										58
									
								
								src/Service/Remote/RetryingFailClientTrait.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/Service/Remote/RetryingFailClientTrait.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,58 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					declare(strict_types=1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Service\Remote;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Exception;
 | 
				
			||||||
 | 
					use Psr\Log\LoggerInterface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					trait RetryingFailClientTrait
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Lepsi zopakovat request kvuli drobnemu vypadku site nebo sluzby (u nedestruktivni operace)
 | 
				
			||||||
 | 
					     * nez hodit klientovi rovnou 500
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param int $count
 | 
				
			||||||
 | 
					     * @param float $sleep
 | 
				
			||||||
 | 
					     * @param array<string> $catchableExceptions
 | 
				
			||||||
 | 
					     * @param LoggerInterface $logger
 | 
				
			||||||
 | 
					     * @param callable $callback
 | 
				
			||||||
 | 
					     * @return mixed
 | 
				
			||||||
 | 
					     * @throws Exception
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected function retryingFailRequest(
 | 
				
			||||||
 | 
					        int $count,
 | 
				
			||||||
 | 
					        float $sleep,
 | 
				
			||||||
 | 
					        array $catchableExceptions,
 | 
				
			||||||
 | 
					        LoggerInterface $logger,
 | 
				
			||||||
 | 
					        callable $callback
 | 
				
			||||||
 | 
					    ): mixed {
 | 
				
			||||||
 | 
					        for ($i = 0; ; $i++) {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                return $callback();
 | 
				
			||||||
 | 
					            } catch (Exception $e) {
 | 
				
			||||||
 | 
					                foreach ($catchableExceptions as $exceptionClass) {
 | 
				
			||||||
 | 
					                    if ($e instanceof $exceptionClass) {
 | 
				
			||||||
 | 
					                        $logger->error("transport: fail request retrying... got catchable exception", [
 | 
				
			||||||
 | 
					                            'exception' => $e,
 | 
				
			||||||
 | 
					                            'try' => $i
 | 
				
			||||||
 | 
					                        ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        usleep((int) ($sleep * 1_000_000));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        if ($i == $count) {
 | 
				
			||||||
 | 
					                            throw $e;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        continue 2;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                throw $e;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // phpstan fail
 | 
				
			||||||
 | 
					        return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										56
									
								
								tests/Service/Remote/RetryingFailClientTraitTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								tests/Service/Remote/RetryingFailClientTraitTest.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Tests\Service\Remote;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Service\Remote\RetryingFailClientTrait;
 | 
				
			||||||
 | 
					use App\Tests\Common\LoggerTrait;
 | 
				
			||||||
 | 
					use PHPUnit\Framework\TestCase;
 | 
				
			||||||
 | 
					use Psr\Log\LoggerInterface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class RetryingFailClientTraitTest extends TestCase {
 | 
				
			||||||
 | 
					    use LoggerTrait;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private int $callCount = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected function setUp(): void
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        parent::setUp(); // TODO: Change the autogenerated stub
 | 
				
			||||||
 | 
					        $this->callCount = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testSuccess() {
 | 
				
			||||||
 | 
					        $trait = new class {
 | 
				
			||||||
 | 
					            use RetryingFailClientTrait {
 | 
				
			||||||
 | 
					                retryingFailRequest as public; // make the method public
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $result = $trait->retryingFailRequest(2, 0, [\RuntimeException::class], $this->getLogger(), function () {
 | 
				
			||||||
 | 
					            $this->callCount = $this->callCount + 1;
 | 
				
			||||||
 | 
					            return 'foo';
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->assertEquals(1, $this->callCount);
 | 
				
			||||||
 | 
					        $this->assertEquals('foo', $result);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function testRetyingFail() {
 | 
				
			||||||
 | 
					        $trait = new class {
 | 
				
			||||||
 | 
					            use RetryingFailClientTrait {
 | 
				
			||||||
 | 
					                retryingFailRequest as public; // make the method public
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $trait->retryingFailRequest(2, 0, [\RuntimeException::class], $this->getLogger(), function () {
 | 
				
			||||||
 | 
					                $this->callCount = $this->callCount + 1;
 | 
				
			||||||
 | 
					                throw new \RuntimeException("test");
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        } catch (\RuntimeException) {
 | 
				
			||||||
 | 
					            // do nothing
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->assertEquals(3, $this->callCount);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user