Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\CircuitBreaker\Examples;
|
||||
|
||||
use App\Framework\CircuitBreaker\CircuitBreakerConfig;
|
||||
use App\Framework\CircuitBreaker\FailurePredicate\FailurePredicateFactory;
|
||||
use App\Framework\Core\ValueObjects\Duration;
|
||||
use App\Framework\HttpClient\Exception\ServerErrorException;
|
||||
use App\Framework\Validation\Exceptions\ValidationException;
|
||||
|
||||
/**
|
||||
* Usage examples for the new FailurePredicate system
|
||||
*/
|
||||
final class FailurePredicateUsageExample
|
||||
{
|
||||
/**
|
||||
* Example 1: Using factory methods for common scenarios
|
||||
*/
|
||||
public function exampleFactoryUsage(): void
|
||||
{
|
||||
// For external services - triggers on server errors, excludes validation errors
|
||||
$externalServiceConfig = CircuitBreakerConfig::forExternalService();
|
||||
|
||||
// For database operations - only triggers on database-related exceptions
|
||||
$databaseConfig = CircuitBreakerConfig::forDatabase();
|
||||
|
||||
// For HTTP clients - comprehensive HTTP error handling
|
||||
$httpClientConfig = CircuitBreakerConfig::forHttpClient();
|
||||
|
||||
// Only timeout errors
|
||||
$timeoutConfig = CircuitBreakerConfig::forTimeoutErrors();
|
||||
|
||||
// Critical errors only (500+ status codes, framework errors)
|
||||
$criticalConfig = CircuitBreakerConfig::strict();
|
||||
}
|
||||
|
||||
/**
|
||||
* Example 2: Using the fluent builder for custom predicates
|
||||
*/
|
||||
public function exampleBuilderUsage(): void
|
||||
{
|
||||
// Complex predicate: Include server errors OR specific exceptions, exclude validation
|
||||
$customPredicate = FailurePredicateFactory::builder()
|
||||
->includeServerErrors() // 5xx HTTP status codes
|
||||
->includeExceptions([
|
||||
ServerErrorException::class,
|
||||
\PDOException::class,
|
||||
])
|
||||
->excludeExceptions([
|
||||
ValidationException::class,
|
||||
\InvalidArgumentException::class,
|
||||
])
|
||||
->includeStatusCodes([429, 503, 504]) // Rate limiting and gateway errors
|
||||
->addCallback(
|
||||
fn (\Throwable $e, string $service) => str_contains($e->getMessage(), 'timeout'),
|
||||
'Timeout detection'
|
||||
)
|
||||
->or() // Use OR logic instead of AND
|
||||
->build();
|
||||
|
||||
$config = CircuitBreakerConfig::withFailurePredicate(
|
||||
failurePredicate: $customPredicate,
|
||||
failureThreshold: 3,
|
||||
recoveryTimeout: Duration::fromMinutes(2)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Example 3: Service-specific predicates
|
||||
*/
|
||||
public function exampleServiceSpecificPredicates(): void
|
||||
{
|
||||
// Different predicates for different services
|
||||
$paymentServicePredicate = FailurePredicateFactory::builder()
|
||||
->includeServerErrors()
|
||||
->includeStatusCodes([429, 502, 503, 504])
|
||||
->excludeExceptions([ValidationException::class])
|
||||
->and()
|
||||
->build();
|
||||
|
||||
$emailServicePredicate = FailurePredicateFactory::builder()
|
||||
->includeExceptions([
|
||||
\App\Framework\HttpClient\Exception\CurlExecutionFailed::class,
|
||||
ServerErrorException::class,
|
||||
])
|
||||
->addCallback(
|
||||
fn (\Throwable $e, string $service) => $service === 'email-service' &&
|
||||
str_contains($e->getMessage(), 'rate limit'),
|
||||
'Email service rate limiting'
|
||||
)
|
||||
->or()
|
||||
->build();
|
||||
|
||||
$paymentConfig = CircuitBreakerConfig::withFailurePredicate($paymentServicePredicate);
|
||||
$emailConfig = CircuitBreakerConfig::withFailurePredicate($emailServicePredicate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Example 4: Advanced combinations with logical operators
|
||||
*/
|
||||
public function exampleAdvancedCombinations(): void
|
||||
{
|
||||
// Predicate that triggers when:
|
||||
// (Server errors OR specific exceptions) AND NOT validation errors
|
||||
$complexPredicate = FailurePredicateFactory::builder()
|
||||
->includeServerErrors()
|
||||
->includeExceptions([
|
||||
ServerErrorException::class,
|
||||
\RuntimeException::class,
|
||||
])
|
||||
->and() // AND logic for above conditions
|
||||
->build();
|
||||
|
||||
// Combine with NOT predicate for validation errors
|
||||
$validationExclusion = FailurePredicateFactory::builder()
|
||||
->includeExceptions([
|
||||
ValidationException::class,
|
||||
\InvalidArgumentException::class,
|
||||
])
|
||||
->build();
|
||||
|
||||
// This creates: (ServerErrors OR RuntimeException) AND NOT ValidationErrors
|
||||
$finalPredicate = FailurePredicateFactory::builder()
|
||||
->addPredicate($complexPredicate)
|
||||
->addPredicate(\App\Framework\CircuitBreaker\FailurePredicate\CompositeFailurePredicate::not([$validationExclusion]))
|
||||
->and()
|
||||
->build();
|
||||
|
||||
$config = CircuitBreakerConfig::withFailurePredicate($finalPredicate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Example 5: Message-based predicates
|
||||
*/
|
||||
public function exampleMessageBasedPredicates(): void
|
||||
{
|
||||
// Trigger only on timeout-related messages
|
||||
$timeoutPredicate = FailurePredicateFactory::builder()
|
||||
->addCallback(
|
||||
\App\Framework\CircuitBreaker\FailurePredicate\CallbackFailurePredicate::messageContains('timeout')
|
||||
->shouldTrigger(...),
|
||||
'Timeout message detection'
|
||||
)
|
||||
->addCallback(
|
||||
\App\Framework\CircuitBreaker\FailurePredicate\CallbackFailurePredicate::messageMatches('/connection.*failed/i')
|
||||
->shouldTrigger(...),
|
||||
'Connection failure pattern'
|
||||
)
|
||||
->or()
|
||||
->build();
|
||||
|
||||
$config = CircuitBreakerConfig::withFailurePredicate($timeoutPredicate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Example 6: Testing and debugging predicates
|
||||
*/
|
||||
public function exampleTestingPredicates(): void
|
||||
{
|
||||
// Never trigger (useful for testing)
|
||||
$neverTrigger = FailurePredicateFactory::never();
|
||||
|
||||
// Always trigger (useful for testing)
|
||||
$alwaysTrigger = FailurePredicateFactory::always();
|
||||
|
||||
// Custom test predicate
|
||||
$testPredicate = FailurePredicateFactory::builder()
|
||||
->addCallback(
|
||||
fn (\Throwable $e, string $service) =>
|
||||
$service === 'test-service' && get_class($e) === \RuntimeException::class,
|
||||
'Test-specific predicate'
|
||||
)
|
||||
->build();
|
||||
|
||||
$testConfig = CircuitBreakerConfig::withFailurePredicate($testPredicate);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user