From 07f8ae467c10fd625fe3cea30e2c9f329e687145 Mon Sep 17 00:00:00 2001 From: Christopher Vagnetoft Date: Sun, 15 Dec 2024 13:24:57 +0100 Subject: [PATCH] Make CommandBus use CommandResolverInterface * Add CommandResolverInterface to resolve commands. * Replace single CommandRegistry with CommandResolverInterface[] in CommandBus. * Make CommandRegistry implement CommandResolverInterface. --- src/CommandBus.php | 79 +++++++++++++++++++++++++++++--- src/CommandBusClient.php | 4 +- src/CommandRegistry.php | 2 +- src/CommandResolverInterface.php | 19 ++++++++ 4 files changed, 95 insertions(+), 9 deletions(-) create mode 100644 src/CommandResolverInterface.php diff --git a/src/CommandBus.php b/src/CommandBus.php index f85dc77..9627230 100644 --- a/src/CommandBus.php +++ b/src/CommandBus.php @@ -13,30 +13,92 @@ class CommandBus implements CommandBusInterface { use EventEmitterTrait; - private CommandRegistry $commandRegistry; + /** @var array */ + private $resolvers = []; private SplObjectStorage $connections; private SplObjectStorage $servers; - public function __construct(CommandRegistry $commandRegistry) + public function __construct(?CommandResolverInterface $commands=null) { - $this->commandRegistry = $commandRegistry; + if ($commands) { + $this->resolvers[] = $commands; + } $this->connections = new SplObjectStorage(); $this->servers = new SplObjectStorage(); } - public function getRegistry(): CommandRegistry + /** + * Get the command registry + * + * @deprecated Use getCommandNames() instead + * @return null + */ + public function getRegistry(): ?CommandRegistry { - return $this->commandRegistry; + return null; // $this->commandRegistry; } + /** + * Add a CommandResolver + * + * @param CommandResolverInterface $resolver + * @return void + */ + public function addResolver(CommandResolverInterface $resolver): void + { + $this->resolvers[] = $resolver; + } + + /** + * Get the names of defined commands + * + * @return array + */ + public function getCommandNames(): array + { + $commands = []; + foreach ($this->resolvers as $resolver) { + $commands = array_merge($commands, $resolver->getNames()); + } + sort($commands); + return array_unique($commands); + } + + /** + * Find a command by searching through the resolvers + * + * @param string $command + * @return Command|null + */ + public function findCommand(string $command): ?Command + { + foreach ($this->resolvers as $resolver) { + if ($found = $resolver->find($command)) + return $found; + } + return null; + } + + /** + * Add a server listener + * + * @param ServerInterface $server + * @return void + */ public function addServer(ServerInterface $server): void { $this->servers->attach($server); $server->on('connection', $this->onServerConnection(...)); } + /** + * Remove a server listener + * + * @param ServerInterface $server + * @return void + */ public function removeServer(ServerInterface $server): void { $server->close(); @@ -44,6 +106,11 @@ class CommandBus implements CommandBusInterface $this->servers->detach($server); } + /** + * Close and shutdown the servers + * + * @return void + */ public function close(): void { foreach ($this->servers as $server) { @@ -106,7 +173,7 @@ class CommandBus implements CommandBusInterface private function executeContext(Context $context): PromiseInterface { - $command = $this->commandRegistry->find($context->getCommandName()); + $command = $this->findCommand($context->getCommandName()); if (!$command) return new Promise(function (callable $resolve) use ($context) { throw new \RuntimeException("Unable to resolve command: ".$context->getCommandName()); }); diff --git a/src/CommandBusClient.php b/src/CommandBusClient.php index d1d7989..5d87f37 100644 --- a/src/CommandBusClient.php +++ b/src/CommandBusClient.php @@ -38,8 +38,8 @@ class CommandBusClient implements CommandBusInterface { $this->commandRegistry = $commandRegistry; if ($commandRegistry) { - $commandRegistry->on(CommandRegistry::EVENT_REGISTERED, $this->onCommandRegistered(...)); - $commandRegistry->on(CommandRegistry::EVENT_UNREGISTERED, $this->onCommandUnregistered(...)); + $this->commandRegistry->on(CommandRegistry::EVENT_REGISTERED, $this->onCommandRegistered(...)); + $this->commandRegistry->on(CommandRegistry::EVENT_UNREGISTERED, $this->onCommandUnregistered(...)); } $this->connector = $connector??new TcpConnector(); } diff --git a/src/CommandRegistry.php b/src/CommandRegistry.php index a511e74..9651e1f 100644 --- a/src/CommandRegistry.php +++ b/src/CommandRegistry.php @@ -8,7 +8,7 @@ use Evenement\EventEmitterTrait; * A collection of commands that can be executed via CommandBusInterface * */ -class CommandRegistry implements EventEmitterInterface +class CommandRegistry implements CommandResolverInterface, EventEmitterInterface { use EventEmitterTrait; diff --git a/src/CommandResolverInterface.php b/src/CommandResolverInterface.php new file mode 100644 index 0000000..4d69415 --- /dev/null +++ b/src/CommandResolverInterface.php @@ -0,0 +1,19 @@ +