apip-ddd icon indicating copy to clipboard operation
apip-ddd copied to clipboard

Add async commands

Open javaDeveloperKid opened this issue 1 year ago • 2 comments

Hi, I am using this repository as base for my new project. However this repo does not implement async commands and as a consequence it does not show how to consider async commands inside a command bus implementation.

I rewritten the MessengerCommandBus implementation however this does not satisfy PHPStan as returning null for async commands results in error

Method MessengerCommandBus::dispatch() should return T but returns null.                                
💡 Type null is not always the same as T. It breaks the contract for some argument types, typically subtypes.
final class MessengerCommandBus implements CommandBusInterface
{
    public function __construct(MessageBusInterface $commandBus)
    {
        $this->messageBus = $commandBus;
    }

    /**
     * @template T
     *
     * @param CommandInterface<T> $command
     *
     * @return T
     */
    public function dispatch(CommandInterface $command): mixed
    {
        try {
            $envelope = $this->messageBus->dispatch($message);
            /** @var HandledStamp[] $handledStamps */
            $handledStamps = $envelope->all(HandledStamp::class);

            if (!$handledStamps) {
                // async command
                return null;
            }
            
            if (\count($handledStamps) > 1) {
                $handlers = implode(', ', array_map(fn (HandledStamp $stamp): string => sprintf('"%s"', $stamp->getHandlerName()), $handledStamps));

                throw new LogicException(sprintf('Message of type "%s" was handled multiple times. Only one handler is expected when using "%s::%s()", got %d: %s.', get_debug_type($envelope->getMessage()), static::class, __FUNCTION__, \count($handledStamps), $handlers));
            }

            return $handledStamps[0]->getResult();
        } catch (HandlerFailedException $e) {
            if ($exception = current($e->getWrappedExceptions())) {
                throw $exception;
            }

            throw $e;
        }
    }
}

javaDeveloperKid avatar Apr 07 '24 20:04 javaDeveloperKid