chore: complete update
This commit is contained in:
103
src/Framework/CommandBus/DefaultCommandBus.php
Normal file
103
src/Framework/CommandBus/DefaultCommandBus.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\CommandBus;
|
||||
|
||||
use App\Application\Auth\LoginUser;
|
||||
use App\Framework\CommandBus\Exceptions\NoHandlerFound;
|
||||
use App\Framework\CommandBus\Middleware\DatabaseTransactionMiddleware;
|
||||
use App\Framework\CommandBus\Middleware\PerformanceMonitoringMiddleware;
|
||||
use App\Framework\Context\ExecutionContext;
|
||||
use App\Framework\Context\ContextType;
|
||||
use App\Framework\DI\Container;
|
||||
use App\Framework\DI\DefaultContainer;
|
||||
use App\Framework\Queue\FileQueue;
|
||||
use App\Framework\Queue\Queue;
|
||||
use App\Framework\Queue\RedisQueue;
|
||||
|
||||
final readonly class DefaultCommandBus implements CommandBus
|
||||
{
|
||||
public function __construct(
|
||||
private CommandHandlersCollection $commandHandlers,
|
||||
private Container $container,
|
||||
private ExecutionContext $executionContext,
|
||||
private Queue $queue = new RedisQueue(host: 'redis'),
|
||||
private array $middlewares = [
|
||||
PerformanceMonitoringMiddleware::class,
|
||||
DatabaseTransactionMiddleware::class,
|
||||
],
|
||||
) {}
|
||||
|
||||
public function dispatch(object $command): mixed
|
||||
{
|
||||
$contextType = $this->executionContext->getType();
|
||||
error_log("CommandBus Debug: Execution context: {$contextType->value}");
|
||||
error_log("CommandBus Debug: Context metadata: " . json_encode($this->executionContext->getMetadata()));
|
||||
|
||||
// Context-basierte Queue-Entscheidung
|
||||
if ($this->shouldQueueInContext($command, $contextType)) {
|
||||
error_log("CommandBus Debug: Job wird in Queue eingereiht: " . $command::class);
|
||||
$this->queue->push($command);
|
||||
return null;
|
||||
}
|
||||
|
||||
error_log("CommandBus Debug: Job wird direkt ausgeführt: " . $command::class);
|
||||
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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user