- 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.
103 lines
3.5 KiB
PHP
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();
|
|
}
|
|
}
|