- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
Async ErrorBoundary System
Complete async error boundary implementation using the framework's async components (FiberManager, AsyncPromise, etc.).
Components
Core Classes
AsyncErrorBoundary- Main async error boundary using framework'sFiberManagerandAsyncPromiseAsyncErrorBoundaryFactory- Factory for creating async boundaries with different configurationsAsyncBulkResult- Result object for batch async operations with success/error trackingAsyncBoundaryFailedException- Exception for when both operation and fallback failAsyncCircuitBreakerOpenException- Exception for circuit breaker open state
Framework Integration
Uses Framework Async Components
FiberManager- Fiber-based async execution with batching and throttlingAsyncPromise- Promise-based async/await patternClock/Timer- Time management using framework value objectsDuration/Timestamp- Proper time value objects
ErrorBoundary Integration
- Circuit breaker state management via
BoundaryCircuitBreakerManager - Event publishing via
BoundaryEventPublisher - Metrics and observability support
- Same retry strategies and configuration as sync boundaries
Usage Examples
Basic Async Operation
$factory = new AsyncErrorBoundaryFactory($fiberManager, $clock, $timer);
$boundary = $factory->createForExternalService('payment_api');
$promise = $boundary->executeAsync(
operation: fn() => $paymentApi->processPayment($request),
fallback: fn() => $this->createOfflinePaymentRecord($request)
);
$result = $promise->await();
Concurrent Operations
$operations = [
'user_data' => fn() => $userService->getUserData($userId),
'preferences' => fn() => $preferenceService->getPreferences($userId),
'notifications' => fn() => $notificationService->getUnread($userId),
];
$promise = $boundary->executeConcurrent($operations);
$results = $promise->await();
// Results: ['user_data' => ..., 'preferences' => ..., 'notifications' => ...]
Batch Processing
$batchBoundary = $factory->createForBatchProcessing('email_sending');
$promise = $batchBoundary->executeBatch(
items: $emailQueue,
processor: fn($email) => $mailService->send($email),
maxConcurrency: 5
);
$bulkResult = $promise->await();
echo "Success rate: " . $bulkResult->getSuccessRate()->toFloat() * 100 . "%\n";
echo "Processed: {$bulkResult->successfulOperations}/{$bulkResult->totalOperations}\n";
Timeout Handling
$promise = $boundary->executeWithTimeout(
operation: fn() => $heavyComputation->process($data),
timeout: Duration::fromSeconds(30),
fallback: fn() => $this->getCachedResult($data)
);
try {
$result = $promise->await();
} catch (AsyncTimeoutException $e) {
// Handle timeout
}
Circuit Breaker with Async
$promise = $boundary->executeWithCircuitBreaker(
operation: fn() => $externalApi->call($request),
fallback: fn() => $this->getDefaultResponse()
);
$result = $promise->await();
Factory Configurations
External Service Boundary
$boundary = $factory->createForExternalService('payment_service');
- Retry strategy with exponential backoff
- Circuit breaker enabled
- Appropriate timeouts for external calls
Database Boundary
$boundary = $factory->createForDatabase('user_queries');
- Fast fail for database issues
- Connection pooling aware
- Optimized for database operation patterns
Background Job Boundary
$boundary = $factory->createForBackgroundJob('email_processor');
- Higher retry counts
- Longer timeouts
- Batch error tolerance
High Throughput Boundary
$boundary = $factory->createForHighThroughput('api_endpoints');
- Minimal retries for speed
- Higher circuit breaker thresholds
- Optimized for high-volume operations
Async Result Types
AsyncBulkResult
$bulkResult = $promise->await();
// Statistics
$successRate = $bulkResult->getSuccessRate(); // Percentage object
$errorRate = $bulkResult->getErrorRate(); // Percentage object
// Individual results
$userResult = $bulkResult->getResult('user_1');
$userError = $bulkResult->getError('user_1');
// Status checks
$hasAnyErrors = $bulkResult->hasErrors();
$isCompleteSuccess = $bulkResult->isCompleteSuccess();
Event Integration
Async boundaries publish the same events as sync boundaries:
BoundaryExecutionSucceeded- Successful async operationBoundaryExecutionFailed- Failed async operationBoundaryFallbackExecuted- Fallback was usedBoundaryTimeoutOccurred- Operation timed out
Promise Chaining
$promise = $boundary->executeAsync(fn() => $service->getData())
->then(fn($data) => $this->processData($data))
->then(fn($processed) => $this->saveData($processed))
->catch(fn($error) => $this->handleError($error))
->finally(fn() => $this->cleanup());
$result = $promise->await();
Concurrent with Fallbacks
$operations = [
'primary_data' => fn() => $primaryService->getData(),
'backup_data' => fn() => $backupService->getData(),
];
$fallbacks = [
'primary_data' => fn() => $cache->get('primary_data'),
'backup_data' => fn() => $cache->get('backup_data'),
];
$promise = $boundary->executeConcurrent($operations, $fallbacks);
$results = $promise->await();
Health Monitoring
// Async health check
$healthPromise = $boundary->getCircuitHealthAsync();
$health = $healthPromise->await();
if ($health && !$health['is_healthy']) {
$this->alerting->sendAlert("Boundary {$boundary->boundaryName} is unhealthy");
}
// Async circuit reset
$resetPromise = $boundary->resetCircuitAsync();
$resetPromise->await();
Performance Benefits
Framework Integration Benefits
- Fiber-based: Uses PHP 8.1+ Fibers for true async execution
- Batching: Framework's
FiberManagerhandles optimal batching - Throttling: Built-in concurrency control
- Timeout Management: Framework's timeout handling with proper cleanup
Error Boundary Benefits
- Graceful Degradation: Async fallbacks prevent service interruption
- Circuit Breaking: Prevents cascade failures in async operations
- Retry Logic: Async retry with proper delays
- Observability: Events and metrics for async operations
Best Practices
Concurrency Management
// Good: Use factory methods for appropriate concurrency
$batchBoundary = $factory->createForBatchProcessing('data_sync');
$bulkResult = $batchBoundary->executeBatch($items, $processor, 10);
// Good: Throttle concurrent operations
$results = $fiberManager->throttled($operations, 5);
Error Handling
// Good: Provide meaningful fallbacks
$promise = $boundary->executeAsync(
operation: fn() => $externalService->getData(),
fallback: fn() => $this->getCachedData() // Always have a fallback
);
// Good: Handle different error types
try {
$result = $promise->await();
} catch (AsyncCircuitBreakerOpenException $e) {
// Circuit breaker is open
} catch (AsyncBoundaryFailedException $e) {
// Both operation and fallback failed
$originalError = $e->getOriginalException();
$fallbackError = $e->getFallbackException();
}
Performance Optimization
// Good: Use appropriate configurations
$highThroughputBoundary = $factory->createForHighThroughput('api_calls');
$batchBoundary = $factory->createForBatchProcessing('data_processing');
// Good: Monitor performance
$bulkResult = $batchBoundary->executeBatch($items, $processor);
$this->metrics->record('batch_success_rate', $bulkResult->getSuccessRate());