Files
michaelschiemer/src/Framework/CommandBus/DefaultCommandBus.php
Michael Schiemer fc3d7e6357 feat(Production): Complete production deployment infrastructure
- Add comprehensive health check system with multiple endpoints
- Add Prometheus metrics endpoint
- Add production logging configurations (5 strategies)
- Add complete deployment documentation suite:
  * QUICKSTART.md - 30-minute deployment guide
  * DEPLOYMENT_CHECKLIST.md - Printable verification checklist
  * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle
  * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference
  * production-logging.md - Logging configuration guide
  * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation
  * README.md - Navigation hub
  * DEPLOYMENT_SUMMARY.md - Executive summary
- Add deployment scripts and automation
- Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment
- Update README with production-ready features

All production infrastructure is now complete and ready for deployment.
2025-10-25 19:18:37 +02:00

103 lines
3.5 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Framework\CommandBus;
use App\Framework\CommandBus\Exceptions\NoHandlerFound;
use App\Framework\CommandBus\Middleware\DatabaseTransactionMiddleware;
use App\Framework\CommandBus\Middleware\PerformanceMonitoringMiddleware;
use App\Framework\Context\ContextType;
use App\Framework\Context\ExecutionContext;
use App\Framework\DI\Container;
use App\Framework\Logging\Logger;
use App\Framework\Queue\Queue;
final class DefaultCommandBus implements CommandBus
{
public function __construct(
private CommandHandlersCollection $commandHandlers,
private Container $container,
private ExecutionContext $executionContext,
private Queue $queue,
private Logger $logger,
private array $middlewares = [
PerformanceMonitoringMiddleware::class,
DatabaseTransactionMiddleware::class,
],
) {}
public function dispatch(object $command): mixed
{
$contextType = $this->executionContext->getType();
// Debug logging removed for production - only log errors
// Context-basierte Queue-Entscheidung
if ($this->shouldQueueInContext($command, $contextType)) {
// No logging for normal queue operations in production
$this->queue->push($command);
return null;
}
// No logging for normal direct execution in production
return $this->executeCommand($command);
}
private function executeCommand(object $command): mixed
{
$handlerExecutor = function (object $command): mixed {
$handler = $this->commandHandlers->get($command::class);
if ($handler === null) {
throw NoHandlerFound::forCommand($command::class);
}
// $handler = $this->commandHandlers[get_class($command)];
$handlerClass = $this->container->get($handler->class);
return $handlerClass->{$handler->method}($command);
};
$pipeline = array_reduce(
array_reverse($this->middlewares),
function (callable $next, string $middlewareClass): callable {
return function (object $command) use ($middlewareClass, $next): mixed {
/** @var Middleware $middleware */
$middleware = $this->container->get($middlewareClass);
return $middleware->handle($command, $next);
};
},
$handlerExecutor
);
return $pipeline($command);
}
private function shouldQueueInContext(object $command, ContextType $context): bool
{
$ref = new \ReflectionClass($command);
$hasQueueAttribute = ! empty($ref->getAttributes(ShouldQueue::class));
if (! $hasQueueAttribute) {
return false; // Ohne #[ShouldQueue] Attribut nie queuen
}
// Context-basierte Entscheidung
return match($context) {
ContextType::WORKER => false, // Worker: NIEMALS queuen
ContextType::CONSOLE => false, // Artisan: meist direkt
ContextType::TEST => false, // Tests: immer direkt
ContextType::CLI_SCRIPT => true, // CLI Scripts: normal queuen
ContextType::WEB => true, // Web: Standard Queue-Verhalten
};
}
public function __debugInfo(): ?array
{
return $this->commandHandlers->toArray();
}
}