/**
  * {@inheritdoc}
  */
 public function send($routingKey, CommandMessageInterface $command, CommandCallbackInterface $callback = null)
 {
     $destination = $this->template->getRoutingDestination($command->getCommandName(), $routingKey);
     if (null === $destination) {
         $destination = $this->findSuitableNode($command);
         $this->template->setRoutingDestination($destination, $command->getCommandName(), $routingKey);
     }
     // dispatch locally if destination matches this node
     if ($this->template->getNodeName() === $destination) {
         $this->localSegment->dispatch($command, $callback);
         return;
     }
     $awaitReply = $callback ? true : false;
     $dispatchMessage = new DispatchMessage($command, $this->serializer, $awaitReply);
     $this->template->enqueueCommand($destination, $dispatchMessage->toBytes());
     if ($awaitReply) {
         $reply = $this->template->readCommandReply($command->getIdentifier());
         if (null === $reply) {
             $callback->onFailure(new CommandTimeoutException($command->getIdentifier()));
             return;
         }
         $replyMessage = ReplyMessage::fromBytes($this->serializer, $reply[1]);
         if ($replyMessage->isSuccess()) {
             $callback->onSuccess($replyMessage->getReturnValue());
         } else {
             $callback->onFailure(new CommandDispatchException($replyMessage->getError()));
         }
     }
 }
 public function testFromAndToBytes()
 {
     $serializer = new JMSSerializer();
     $commandMessage = GenericCommandMessage::asCommandMessage(new ResultPayload("string", 10, 5.1));
     $dispatchMessage1 = new DispatchMessage($commandMessage, $serializer, false);
     $bytes = $dispatchMessage1->toBytes();
     $dispatchMessage2 = DispatchMessage::fromBytes($serializer, $bytes);
     $this->assertEquals($dispatchMessage1->getCommandIdentifier(), $dispatchMessage2->getCommandIdentifier());
     $this->assertEquals($dispatchMessage1->isExpectReply(), $dispatchMessage2->isExpectReply());
     $this->assertEquals($dispatchMessage1->getCommandMessage(), $dispatchMessage2->getCommandMessage());
     $this->assertFalse($dispatchMessage1->isExpectReply());
     $this->assertFalse($dispatchMessage2->isExpectReply());
 }
 public function processCommand()
 {
     $data = $this->template->dequeueCommand();
     if (null === $data) {
         $this->logger->info('Timeout while waiting for commands, re-entering loop');
         return;
     }
     $dispatchMessage = DispatchMessage::fromBytes($this->serializer, $data[1]);
     $self = $this;
     $successCallback = function ($result) use($dispatchMessage, $self) {
         $message = new ReplyMessage($dispatchMessage->getCommandIdentifier(), $self->serializer, $result);
         $self->template->writeCommandReply($dispatchMessage->getCommandIdentifier(), $message->toBytes());
     };
     $failureCallback = function (\Exception $cause) use($dispatchMessage, $self) {
         $message = new ReplyMessage($dispatchMessage->getCommandIdentifier(), $self->serializer, $cause, false);
         $self->template->writeCommandReply($dispatchMessage->getCommandIdentifier(), $message->toBytes());
     };
     $this->localSegment->dispatch($dispatchMessage->getCommandMessage(), $dispatchMessage->isExpectReply() ? new ClosureCommandCallback($successCallback, $failureCallback) : null);
 }