Я реализую приложение PHP с CQRS.
Допустим, у меня есть CreateOrderCommand
, и когда я это сделаю
$command = new CreateOrderCommand(/** some data**/);
$this->commandBus->handle($command);
CommandBus теперь просто передает команду соответствующему классу CreateOrderCommandHandler
так же просто, как:
abstract class SimpleCommandBus implements CommandBus
{
/** @var ICommandHandlerLocator */
protected $locator;
/**
* Executes command
*
* @param Command $command
*/
public function handle(Command $command)
{
$handler = $this->locator->getCommandHandler($command);
$handler->handle($command);
}
}
Все нормально.
Но обработка - это недействительный метод, поэтому я ничего не знаю о прогрессе или результате. Что я могу сделать, чтобы иметь возможность, например, запустить CreateOrderCommand
, а затем в том же процессе получить вновь созданный идентификатор объекта (возможно, с некоторым пассивным ожиданием его создания)?
public function createNewOrder(/** some data**/){
$command = new CreateOrderCommand(/** some data**/);
$this->commandBus->handle($command);
// something that will wait until command is done
$createdOrder = // some magic that retrieves some adress to result data
return $createdOrder;
}
И чтобы приблизиться к тому, что может предоставить CQRS, командная шина должна иметь реализацию RabbitMqCommandBus
, которая просто сериализует команду и отправляет ее в очередь кролика.
Итак, тогда процесс, который, наконец, обрабатывает команду, может быть неким запущенным потребителем, и здесь требуется какая-то связь между процессами - чтобы иметь возможность каким-то образом информировать исходный пользовательский процесс от потребителя, что это сделано (с некоторой информацией, например, идентификатором новый объект).
Я знаю, что есть решение с GUID - я мог бы пометить команду с помощью GUID. Но что тогда:
public function createNewOrder(/** some data**/){
$command = new CreateOrderCommand(/** some data**/);
$this->commandBus->handle($command);
$guid = $command->getGuid();
// SOME IMPLEMENTATION
return $createdOrder;
}
НЕКОТОРАЯ РЕАЛИЗАЦИЯ должна выполнять некоторую проверку событий (поэтому мне также нужно реализовать некоторую систему событий) по команде с определенным GUID, чтобы иметь возможность, например, отображать ход выполнения или OrderCreatedEvent
просто возвращать свой идентификатор, который я получил бы от этого события. Процесс-потребитель, который асинхронно обрабатывает команду, может, например, передавать события кролику, а пользовательский клиент будет принимать их и выполнять правильный ответ (например, эхо-прогресс, возврат вновь созданного объекта).
Но как это сделать? И решение с GUID единственное? Каковы приемлемые реализации решений? Или какой момент я упускаю? :)