2017-03-14 1 views
0

Ich habe mich mit einem dieser Vertex-Liebhaber verbunden, wie auch immer der single-threaded Mainframe für mich nicht funktioniert, denn in meinem Server gibt es 50 Datei-Download-Anfragen in einem Moment diese Klasse erstellt habenNebenläufigkeit auf Vertex

public abstract T onRun() throws Exception; 
public abstract void onSuccess(T result); 
public abstract void onException(); 

private static final int poolSize = Runtime.getRuntime().availableProcessors(); 
private static final long maxExecuteTime = 120000; 

private static WorkerExecutor mExecutor; 

private static final String BG_THREAD_TAG = "BG_THREAD"; 

protected RoutingContext ctx; 

private boolean isThreadInBackground(){ 
    return Thread.currentThread().getName() != null && Thread.currentThread().getName().equals(BG_THREAD_TAG); 
} 

//on success will not be called if exception be thrown 
public BackgroundExecutor(RoutingContext ctx){ 

    this.ctx = ctx; 

    if(mExecutor == null){ 
     mExecutor = MyVertxServer.vertx.createSharedWorkerExecutor("my-worker-pool",poolSize,maxExecuteTime); 
    } 

    if(!isThreadInBackground()){ 

    /** we are unlocking the lock before res.succeeded , because it might take long and keeps any thread waiting */ 

    mExecutor.executeBlocking(future -> { 
     try{ 

       Thread.currentThread().setName(BG_THREAD_TAG); 

       T result = onRun(); 
       future.complete(result); 

     }catch (Exception e) { 
      GUI.display(e); 
      e.printStackTrace(); 
      onException(); 
      future.fail(e); 
     } 

       /** false here means they should not be parallel , and will run without order multiple times on same context*/ 
      },false, res -> { 

       if(res.succeeded()){ 
        onSuccess((T)res.result()); 
       } 

      }); 

    }else{ 


     GUI.display("AVOIDED DUPLICATE BACKGROUND THREADING"); 
     System.out.println("AVOIDED DUPLICATE BACKGROUND THREADING"); 

     try{ 

       T result = onRun(); 

       onSuccess((T)result); 

     }catch (Exception e) { 
      GUI.display(e); 
      e.printStackTrace(); 
      onException();   
     } 
    } 

} 

die Handler ermöglicht es zu erweitern und wie diese

public abstract class DefaultFileHandler implements MyHttpHandler{ 

public abstract File getFile(String suffix); 

@Override 
public void Handle(RoutingContext ctx, VertxUtils utils, String suffix) { 
    new BackgroundExecutor<Void>(ctx) { 

     @Override 
     public Void onRun() throws Exception { 

      File file = getFile(URLDecoder.decode(suffix, "UTF-8")); 

      if(file == null || !file.exists()){ 
       utils.sendResponseAndEnd(ctx.response(),404); 
       return null; 
      }else{ 
       utils.sendFile(ctx, file); 
      } 
      return null; 
     } 

     @Override 
     public void onSuccess(Void result) {} 

     @Override 
     public void onException() { 
      utils.sendResponseAndEnd(ctx.response(),404); 
     } 
    }; 
} 

und hier zu verwenden ist, wie ich meine initialisieren VertX Server

vertx.deployVerticle(MainDeployment.class.getCanonicalName(),res -> { 
      if (res.succeeded()) { 

       GUI.display("Deployed"); 

       } else { 
       res.cause().printStackTrace(); 
       } 
      }); 

    server.requestHandler(router::accept).listen(port); 

und hier ist meine MainDeployment Klasse

public class MainDeployment extends AbstractVerticle{ 

    @Override 
    public void start() throws Exception { 

    // Different ways of deploying verticles 

    // Deploy a verticle and don't wait for it to start 

    for(Entry<String, MyHttpHandler> entry : MyVertxServer.map.entrySet()){ 
     MyVertxServer.router.route(entry.getKey()).handler(new Handler<RoutingContext>() { 

      @Override 
      public void handle(RoutingContext ctx) { 

       String[] handlerID = ctx.request().uri().split(ctx.currentRoute().getPath()); 

       String suffix = handlerID.length > 1 ? handlerID[1] : null; 
       entry.getValue().Handle(ctx, new VertxUtils(), suffix); 

      } 
     }); 
    } 

    } 
} 

dies ganz gut funktioniert, wann und wo ich es brauche, aber ich frage mich immer noch, wenn ist es eine bessere Art und Weise concurencies wie diese auf VertX, wenn so ein Beispiel zu handhaben würde sehr geschätzt werden. Vielen Dank

Antwort

1

Ich verstehe nicht vollständig Ihr Problem und Gründe für Ihre Lösung. Warum implementieren Sie nicht ein vertikum, um Ihre http-Uploads zu verarbeiten und mehrfach zu implementieren? Ich denke, die Handhabung von 50 gleichzeitigen Uploads sollte für vert.x ein Kinderspiel sein.

Wenn eine verticle Entfalten eines verticle Namen verwenden, können Sie die Anzahl der verticle Instanzen angeben, die Sie bereitstellen möchten:

DeploymentOptions options = new DeploymentOptions().setInstances(16); vertx.deployVerticle("com.mycompany.MyOrderProcessorVerticle", options);

Dies ist nützlich für leicht auf mehrere Cores skalieren. Zum Beispiel könnten Sie eine Webserver-Verticle zur Bereitstellung und mehrere Cores auf Ihrem Computer haben, sodass Sie mehrere Instanzen bereitstellen müssen, um alle Kerne zu nutzen.

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

0

VertX ist ein gut konzipiertes Modell, so dass ein Concurrency Problem tritt nicht auf. Im Allgemeinen empfiehlt Vertex das Multithread-Modell nicht. (weil die Behandlung ist nicht leicht.)

Wenn Sie Multi-Thread-Modell auswählen, können Sie über gemeinsam genutzte Daten denken ..

einfach, wenn Sie gerade erst Ereignisschleife Gebiet geteilt werden sollen, zunächst alle, stellen Sie sicher, überprüfen Sie eine Anzahl von CPU-Kernen. und richten Sie dann die Anzahl der Instanzen ein.

DeploymentOptions options = new DeploymentOptions().setInstances(4); 
vertx.deployVerticle("com.mycompany.MyOrderProcessorVerticle", options); 

Aber, wenn Sie 4cores der CPU haben, haben Sie mehr als 4 Fällen nicht einrichten. Wenn Sie auf Nummer vier oder mehr eingestellt sind, wird die Leistung nicht verbessert.

vertx concurrency reference

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