2017-05-09 1 views
1

j'ai écrit le code suivant:vert.x: publier et messages de bus consommeront d'événements

public class VertxApp { 

    public static void main(String[] args) { // This is OK 
     Vertx vertx = Vertx.vertx(); 
     vertx.deployVerticle(new ReceiveVerticle()); // line A 
     vertx.deployVerticle(new SendVerticle());  // line B 
    } 
} 

public class ReceiveVerticle extends AbstractVerticle{ 

    @Override 
    public void start(Future<Void> startFuture) { 
     vertx.eventBus().consumer("address", message -> { 
      System.out.println("message received by receiver"); 
      System.out.println(message.body()); 
     }); 
    } 
} 

public class SendVerticle extends AbstractVerticle { 

    @Override 
    public void start(Future<Void> startFuture) throws InterruptedException { 
     System.out.println("SendVerticle started!"); 
     int i = 0; 

     for (i = 0; i < 5; i++) { 
      System.out.println("Sender sends a message " + i); 
      vertx.eventBus().publish("address", "message" + i); 
     } 
    } 
} 

Ce code est incompatible. Il y a une condition de course. Si je cours le code plusieurs fois, parfois tous les 5 messages envoyés sont consommés, et parfois aucun d'eux n'est consommé.

Pouvez-vous expliquer pourquoi il y a un problème de concurrence ici et comment il peut être résolu?

Répondre

4

Il n'y a pas de condition de concurrence, le déploiement d'une verticule est une opération asynchrone et votre verticule de récepteur peut enregistrer le consommateur après le verticle de l'expéditeur a envoyé les messages.

Pour faire des opérations sûres se produisent dans l'ordre, utilisez la méthode deploy qui prend un argument de gestionnaire:

Vertx vertx = Vertx.vertx(); 
vertx.deployVerticle(new ReceiveVerticle(), ar -> { 
    if (ar.succeeded()) { 
     vertx.deployVerticle(new SendVerticle()); 
    } else { 
     // handle the problem -> ar.cause() 
    } 
});