RabbitMQ wait for multiple queues to finish

后端 未结 5 1790
傲寒
傲寒 2021-02-05 15:15

Ok here is an overview of what\'s going on:

    M <-- Message with unique id of 1234
    |
    +-Start Queue
    |
    |
    | <-- Exchange
   /|\\
  / | \         


        
5条回答
  •  情话喂你
    2021-02-05 15:25

    In addition to my RPC based answer I want to add another one which is based on EIP aggregator pattern.

    The idea is next: Everything is async, no RPC or other sync things. Every task sends an even when it is done, The aggregator is subscribed to that event. It basically counts tasks and sends task4 message when the counter reaches expected number (in our case 3). I choose a filesystem as a storage for counters for the Sake of simplicity. You can use a database there.

    The producer looks simpler. It just fires and forgets

    get('enqueue.client.producer');
    
    $message = new Message('the task data');
    $message->setCorrelationId(UUID::generate());
    
    $producer->sendCommand('task1', clone $message);
    $producer->sendCommand('task2', clone $message);
    $producer->sendCommand('task3', clone $message);
    

    The task processor has to send an event once its job is done:

    producer = $producer;
        }
    
        public function process(PsrMessage $message, PsrContext $context)
        {
            // do the job
    
            // same for other
            $eventMessage = new Message('the event data');
            $eventMessage->setCorrelationId($message->getCorrelationId());
    
            $this->producer->sendEvent('task_is_done', $eventMessage);
    
            return self::ACK;
        }
    
        public static function getSubscribedCommand()
        {
            return 'task1';
        }
    }
    

    And the aggregator processor:

    producer = $producer;
            $this->rootDir = $rootDir;
        }
    
        public function process(PsrMessage $message, PsrContext $context)
        {
            $expectedNumberOfTasks = 3;
    
            if (false == $cId = $message->getCorrelationId()) {
                return self::REJECT;
            }
    
            try {
                $lockHandler = new LockHandler($cId, $this->rootDir.'/var/tasks');
                $lockHandler->lock(true);
    
                $currentNumberOfProcessedTasks = 0;
                if (file_exists($this->rootDir.'/var/tasks/'.$cId)) {
                    $currentNumberOfProcessedTasks = file_get_contents($this->rootDir.'/var/tasks/'.$cId);
    
                    if ($currentNumberOfProcessedTasks +1 == $expectedNumberOfTasks) {
                        unlink($this->rootDir.'/var/tasks/'.$cId);
    
                        $this->producer->sendCommand('task4', 'the task data');
    
                        return self::ACK;
                    }
                }
    
                file_put_contents($this->rootDir.'/var/tasks/'.$cId, ++$currentNumberOfProcessedTasks);
    
                return self::ACK;
            } finally {
                $lockHandler->release();
            }
        }
    
        public static function getSubscribedTopics()
        {
            return 'task_is_done';
        }
    }
    

提交回复
热议问题