Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The default bus should be RoutableMessageBus #16

Open
MartkCz opened this issue Jan 27, 2025 · 2 comments
Open

The default bus should be RoutableMessageBus #16

MartkCz opened this issue Jan 27, 2025 · 2 comments

Comments

@MartkCz
Copy link
Member

MartkCz commented Jan 27, 2025

When the default bus is not a RoutableMessageBus as it is in Symfony, SyncTransportFactory causes a bug. The SyncTransport currently behaves so that it takes the middlewares from the default bus even though BusNameStamp sets a different bus.

I tried to submit a pull request, but there's a problem with the test because it requires a MessageBus instance. (https://github.com/contributte/messenger/blob/master/tests/Cases/DI/MessengerExtension.routing.phpt#L103)

Here is the fix for BusPass:

	public function loadPassConfiguration(): void
	{
		$builder = $this->getContainerBuilder();
		$config = $this->getConfig();

		$defaultBus = null;

		// Iterate all buses
		foreach ($config->bus as $name => $busConfig) {
			$middlewares = [];

			$builder->addDefinition($this->prefix(sprintf('bus.%s.locator', $name)))
				->setFactory(ContainerServiceHandlersLocator::class, [[]])
				->setAutowired(false);

			if ($busConfig->defaultMiddlewares === true) {
				$middlewares[] = $builder->addDefinition($this->prefix(sprintf('bus.%s.middleware.busStampMiddleware', $name)))
					->setFactory(AddBusNameStampMiddleware::class, [$name])
					->setAutowired(false);

				$middlewares[] = $builder->addDefinition($this->prefix(sprintf('bus.%s.middleware.dispatchAfterCurrentBusMiddleware', $name)))
					->setFactory(DispatchAfterCurrentBusMiddleware::class)
					->setAutowired(false);

				$middlewares[] = $builder->addDefinition($this->prefix(sprintf('bus.%s.middleware.failedMessageProcessingMiddleware', $name)))
					->setFactory(FailedMessageProcessingMiddleware::class)
					->setAutowired(false);
			}

			// Custom middlewares
			foreach ($busConfig->middlewares as $index => $middlewareConfig) {
				$middlewares[] = $builder->addDefinition($this->prefix(sprintf('bus.%s.middleware.custom%sMiddleware', $name, $index)))
					->setFactory($middlewareConfig)
					->setAutowired(false);
			}

			if ($busConfig->defaultMiddlewares === true) {
				$middlewares[] = $builder->addDefinition($this->prefix(sprintf('bus.%s.middleware.sendMiddleware', $name)))
					->setFactory(SendMessageMiddleware::class, [$this->prefix('@routing.locator'), $this->prefix('@event.dispatcher'), $busConfig->allowNoSenders])
					->setAutowired(false)
					->addSetup('setLogger', [$this->prefix('@logger.logger')]);

				$middlewares[] = $builder->addDefinition($this->prefix(sprintf('bus.%s.middleware.handleMiddleware', $name)))
					->setFactory(HandleMessageMiddleware::class, [$this->prefix(sprintf('@bus.%s.locator', $name)), $busConfig->allowNoHandlers])
					->setAutowired(false)
					->addSetup('setLogger', [$this->prefix('@logger.logger')]);
			}

			// Register message bus
			$builder->addDefinition($this->prefix(sprintf('bus.%s.bus', $name)))
				->setFactory($busConfig->class ?? SymfonyMessageBus::class, [$middlewares])
				->setAutowired(false)
				->setTags([MessengerExtension::BUS_TAG => $name]);

			// Register bus wrapper
			if (isset($busConfig->wrapper) || isset(self::BUS_WRAPPERS[$name])) {
				$builder->addDefinition($this->prefix(sprintf('bus.%s.wrapper', $name)))
					->setFactory($busConfig->wrapper ?? self::BUS_WRAPPERS[$name], [$this->prefix(sprintf('@bus.%s.bus', $name))]);
			}

			// Register as fallback bus
			$isDefaultBus = $busConfig->autowired ?? count($builder->findByTag(MessengerExtension::BUS_TAG)) === 0;

			if ($isDefaultBus) {
				$defaultBus = $this->prefix(sprintf('@bus.%s.bus', $name));
			}
		}

		// Register bus container
		$builder->addDefinition($this->prefix('bus.container'))
			->setFactory(NetteContainer::class)
			->setAutowired(false);

		// Register routable bus
		$builder->addDefinition($this->prefix('bus.routable'))
			->setType(MessageBusInterface::class)
			->setFactory(RoutableMessageBus::class, [$this->prefix('@bus.container'), $defaultBus])
			->setAutowired(true);

		// Register bus registry
		$builder->addDefinition($this->prefix('busRegistry'))
			->setFactory(BusRegistry::class, [$this->prefix('@bus.container')]);
	}
@f3l1x
Copy link
Member

f3l1x commented Jan 27, 2025

Hi, I do not get it, can you repreduce it in https://github.com/contributte/messenger-skeleton?

@MartkCz
Copy link
Member Author

MartkCz commented Jan 27, 2025

Sure: https://github.com/MartkCz/contributte-messenger-bug

eventBus has allowNoHandlers set to true so I expect a successful dispatch, but exception No handler for message "App\Domain\LogMessage" was thrown, because messageBus has allowNoHandlers set to false

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants