2016-03-25 5 views
0

Ich baue Mobile Backend API mit Java EE - JAX-RS 2.0 Technologie.Sollten wir immer asynchrone JAX-RS-Ressourcen für das mobile Backend verwenden?

Da die meisten mobilen Client verbraucht sind asynchrone HTTP-Aufrufe

so meine Frage ist:Soll ich asynchrone Funktion für alle JAX-RS-Ressourcen? Und der Grund, wenn nicht?

Die unten ist die Vorlage Mobil Async API

@Path("/async_api") 
public class AsyncResource { 

    @GET 
    @Path("/loadUsers") 
    @Produces(MediaType.APPLICATION_JSON) 
    public void loadUsers(@Suspended AsyncResponse asyncResponse) { 

     //TODO: ManagedExecutorService 

     new Thread(new Runnable() { 

      @Override 
      public void run() { 
       List users = loadBigUsers(); 
       asyncResponse.resume(users); 
      } 

      private List loadBigUsers() { 
       return null; // Return big list 
      } 

     }).start(); 
    } 
} 

Thank you!

+1

Nein. Asynchron auf dem Client bedeutet nicht asynchron auf dem Server und * umgekehrt. * Treffen Sie Ihre eigene Entscheidung an jedem Ende unabhängig. – EJP

+2

Sie sollten Async auf dem Server für lange laufende Aufgaben verwenden, damit die Container-Threads nicht gehalten werden. –

Antwort

5

In JAX-RS werden die @Suspend Annotation und AsyncResponse nur in bestimmten typischen Szenarien benötigt. Das erste Szenario wurde bereits in Ihrem Codebeispiel identifiziert. Es sind lange laufende Aufgaben. In diesem Fall kann AsyncResponse verwendet werden, um lange laufenden Code in einem Hintergrund-Thread auszuführen. Obwohl dies auf den ersten Blick nicht sinnvoll ist, müssen wir uns überlegen, wie ein Anwendungsserver/Container seine Anforderungen behandelt. Normalerweise gibt es einen Pool von Threads, der Clientanforderungen akzeptiert und verarbeitet. Wenn Sie kostspielige Operationen inline in Ihren JAX-RS-Service-Methoden implementieren, wird einer der Threads im Pool für die gesamte Laufzeit blockiert. Mit der AsyncResponse wird der Executor-Thread in den Pool zurückgegeben und andere Anfragen können parallel bedient werden.

@Path("/users") 
public class UserRestService { 

    @GET 
    public void getAllUsers(@Suspend final AsyncResponse asyncResponse) { 
     new Thread(new Runnable(
      @Override 
      public void run() { 
       List<Users> users = UserDAO.loadAllUsers(); 
       asyncResponse.resume(users); 
      } 
     ) {}).start(); 
    } 
} 

Das zweite Anwendungsszenario für AsyncResponse ist die oft von Produzenten Konsummuster gesehen Muster. Angenommen, Sie haben eine Warteschlange an die URL https://yourservice.at/queue/next gebunden, dann kann eine @GET Methode für eine Blockierung take() verwendet werden, zum Beispiel eine LinkedBlockingQueue. Unter derselben URL können Sie eine @POST-Methode binden, die Daten zur Warteschlange hinzufügt. In diesem Fall würden Sie die Funktionalität mit der Operation take() in einer AsyncResponse einpacken.

@Path("/queue/next") 
public class MessageQueueService { 

    private static final LinkedBlockingQueue<AsyncResponse> suspendedResponses = new LinkedBlockingQueue<AsyncResponse>(); 

    @GET 
    public void getNextMessage(@Suspend final AsyncResponse asyncResponse) { 
     MessageQueueService.suspendedResponses.put(asyncResponse); 
    } 

    @POST 
    public void putNewMessage(final String message) throws InterruptedException { 
     AsyncResponse asyncResponse = suspendedResponses.take(); // note how this could also block a thread 
     asyncResponse.resume(message); 
    } 
} 

Aus diesen Erklärungen auch sehen können, dass die JAX-RS @Suspended Mechanismus verwendet wird, um eine asynchrone Serverseite Aufgabe zu erstellen. Ob die gleiche Anfrage auch asynchron auf dem Client ausgeführt wird oder nicht, ist eine ganz andere Geschichte.

+0

Danke Matthias Steinbauer! – Loc

Verwandte Themen