Get data from async operations

20 Views Asked by At

In Symfony 6 I need to call a first object (named Script), then this one is going to call a second object (Rule), and this Rule is going to call a last object (Condition) that performs various operations. Once the Condition object finished its work it must send its result back to the Rule object, which is supposed to pass it to the first Script object. I want to use Messenger to manage this workflow bacause I need to store those different objects in a queue and treat them asynchronously. On the other hand I know that Messenger has not been designed to give data back after a message is complete; for that reason I considered making message handlers dispatch events, that each caller object would listen to get its child response:

#[AsMessageHandler]
readonly final class CritereMessageHandler
{
    public function __construct(
        private EntityManagerInterface $em,
        private AlarmHelper $alarmHelper,
        private EventDispatcherInterface $dispatcher
    ) {}

    /**
     * @param CritereMessage $message
     * @return void
     * @throws Exception
     */
    public function __invoke(CritereMessage $message): void
    {
        $critere = $this->em->getRepository(Critere::class)
            ->find($message->getId());
        $query = $this->em->getConnection()->executeQuery($critere->getRequete())->fetchOne();
        $result = $this->alarmHelper->parseEvaluation(
            $query,
            $critere->getEvaluation()->getOperateur(),
            $critere->getEvaluation()->getValeur1(),
            $critere->getEvaluation()->getValeur2()
        );
        $message->setResult($result);

        $this->dispatcher->dispatch(
            new CriteriumResponseEvent($message),
            CriteriumResponseEvent::NAME
        );
    }
}

class CriteriumResponseEvent extends Event
{
    public const NAME = 'alarm.criterium.response';

    public function __construct(private readonly CritereMessage $criterium) {}

    public function getCriterium(): CritereMessage
    {
        return $this->criterium;
    }
}
class AlarmTestCommand extends Command
{
    public function __construct(
        private readonly MessageBusInterface $messageBus,
        private readonly EventDispatcherInterface $dispatcher
    )
    {
        parent::__construct();
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io = new SymfonyStyle($input, $output);

        $envelope = $this->messageBus->dispatch(new CritereMessage('leclair', 2, 'xxx', 'yyy'));
        $this->dispatcher->addListener(CriteriumResponseEvent::NAME, function (CriteriumResponseEvent $event): void {
            // dump is not called
            dump($event);
        });

        $io->success('You have a new command! Now make it your own! Pass --help to see your options.');

        return Command::SUCCESS;
    }
}

My problem is that after various tries, I cannot get data back from event listeners in my main process. I don't understand what I could miss, does anybody see what's wrong ?

Thanks by advance

1

There are 1 best solutions below

0
arsrobota On

I chose a different conception to satisfy my need.