2017-09-21 3 views
2

J'utilise le framework Java VertX et j'essaie de charger plusieurs objets JSON à l'aide de VertX WebClient et d'une simple requête HTTP. Je veux le faire en parallèle pour accélérer le processus.Traitement parallèle des requêtes HTTP VertX

J'ai un objet Endpoint:

import io.vertx.core.Vertx; 
import io.vertx.core.json.JsonObject; 
import io.vertx.ext.web.client.WebClient; 
import io.vertx.ext.web.codec.BodyCodec; 

public final class Endpoint { 

    private final String name; 
    private final String url; 

    public Endpoint (String name, String url) { 
     this.name = name; 
     this.url = url; 
    } 

    public String getName() { 
     return name; 
    } 

    public String getUrl() { 
     return url; 
    } 

    public JsonObject loadJsonObject() { 
     WebClient client = WebClient.create(Vertx.vertx()); 
     client.getAbs(this.getUrl()).as(BodyCodec.jsonObject()).send(handler -> { 
      // what to do 
     }); 
     return null; 
    } 

} 

Dans une autre classe, j'ai la fonction suivante qui doit gérer cela en parallèle (source):

public static void useCompletableFutureWithExecutor(List<Endpoint> tasks) { 
    long start = System.nanoTime(); 
    ExecutorService executor = Executors.newFixedThreadPool(Math.min(tasks.size(), 10)); 
    List<CompletableFuture<JsonObject>> futures = 
     tasks.stream() 
      .map(t -> CompletableFuture.supplyAsync(() -> t.loadJsonObject(), executor)) 
      .collect(Collectors.toList()); 

    List<JsonObject> result = 
     futures.stream() 
       .map(CompletableFuture::join) 
       .collect(Collectors.toList()); 
    long duration = (System.nanoTime() - start)/1_000_000; 
    System.out.printf("Processed %d tasks in %d millis\n", tasks.size(), duration); 
    System.out.println(result); 
    executor.shutdown(); 
} 

Je ne sais pas comment continuer de ce. Le VertX WebClient m'oblige à utiliser un gestionnaire async, ce qui signifie que je ne peux pas retourner le JsonObject directement.

Répondre

0

Votre problème se situe dans la signature de la méthode. Au lieu de public JsonObject loadJsonObject() { commençons par public Future<JsonObject> loadJsonObject() {

Cela signifie qu'au lieu de return null; nous pouvons return future;, et l'avenir serait défini comme Future<JsonObject> future = Future.future();

Ce qui reste est de mettre les données quand il arrive:

future.complete(result); 

Et les résultats finaux ressemblerait à quelque chose comme:

public Future<JsonObject> loadJsonObject() { 
     WebClient client = WebClient.create(Vertx.vertx()); 
     Future<JsonObject> future = Future.future(); 
     client.getAbs(this.getUrl()).as(BodyCodec.jsonObject()).send(handler -> { 
      // Do something with JSON and put in result 
      future.complete(result); 

      // Remember to future.fail() in case something went wrong 
     }); 
     return future; 
    } 

BTW, vous pouvez également utiliser CompositeFuture.all() pour attendre tous vos futurs.

http://vertx.io/docs/vertx-core/java/#_async_coordination