Programmation asynchrone - AWS SDK for Java 1. x

Nous avons annoncé la sortie prochaine end-of-support de AWS SDK for Java (v1). Nous vous recommandons de migrer vers la AWS SDK for Java version v2. Pour les dates, les détails supplémentaires et les informations sur la façon de migrer, reportez-vous à l'annonce associée.

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Programmation asynchrone

Vous pouvez utiliser des méthodes synchrones ou asynchrones pour appeler des opérations sur des services. AWS Les méthodes synchrones bloquent l'exécution du thread jusqu'à ce que le client reçoive une réponse du service. Les méthodes asynchrones renvoient immédiatement, en rendant le contrôle au thread appelant sans attendre de réponse.

Dans la mesure où une méthode asynchrone renvoie avant qu'une réponse ne soit disponible, vous avez besoin d'une solution pour obtenir la réponse quand elle est prête. AWS SDK for Java Il propose deux méthodes : les objets futurs et les méthodes de rappel.

Objets Future Java

Les méthodes asynchrones AWS SDK for Java renvoient un objet Future contenant les résultats de l'opération asynchrone à venir.

Appelez la méthode Future isDone() pour voir si le service a déjà fourni un objet de réponse. Lorsque la réponse est prête, vous pouvez obtenir l'objet de la réponse en appelant la méthode Futureget(). Vous pouvez utiliser ce mécanisme pour interroger régulièrement les résultats de l'opération asynchrone, tandis que votre application continue à travailler sur d'autres éléments.

Voici un exemple d'opération asynchrone qui appelle une Lambda fonction et reçoit un objet Future pouvant contenir un InvokeResultobjet. L'objet InvokeResult est récupéré uniquement après qu'isDone() a la valeur true.

import com.amazonaws.services.lambda.AWSLambdaAsyncClient; import com.amazonaws.services.lambda.model.InvokeRequest; import com.amazonaws.services.lambda.model.InvokeResult; import java.nio.ByteBuffer; import java.util.concurrent.Future; import java.util.concurrent.ExecutionException; public class InvokeLambdaFunctionAsync { public static void main(String[] args) { String function_name = "HelloFunction"; String function_input = "{\"who\":\"SDK for Java\"}"; AWSLambdaAsync lambda = AWSLambdaAsyncClientBuilder.defaultClient(); InvokeRequest req = new InvokeRequest() .withFunctionName(function_name) .withPayload(ByteBuffer.wrap(function_input.getBytes())); Future<InvokeResult> future_res = lambda.invokeAsync(req); System.out.print("Waiting for future"); while (future_res.isDone() == false) { System.out.print("."); try { Thread.sleep(1000); } catch (InterruptedException e) { System.err.println("\nThread.sleep() was interrupted!"); System.exit(1); } } try { InvokeResult res = future_res.get(); if (res.getStatusCode() == 200) { System.out.println("\nLambda function returned:"); ByteBuffer response_payload = res.getPayload(); System.out.println(new String(response_payload.array())); } else { System.out.format("Received a non-OK response from {AWS}: %d\n", res.getStatusCode()); } } catch (InterruptedException | ExecutionException e) { System.err.println(e.getMessage()); System.exit(1); } System.exit(0); } }

Rappels asynchrones

Outre l'utilisation de l'Futureobjet Java pour surveiller l'état des demandes asynchrones, le SDK vous permet également d'implémenter une classe qui utilise l'interface. AsyncHandler AsyncHandlerfournit deux méthodes qui sont appelées en fonction de la manière dont la demande est terminée : onSuccess etonError.

Le principal avantage de l'approche de l'interface de rappel est qu'il vous évite d'avoir à interroger l'objet Future pour savoir à quel moment la demande est terminée. Au lieu de cela, votre code peut immédiatement commencer son activité suivante et s'appuyer sur le kit SDK pour appeler votre gestionnaire au bon moment.

import com.amazonaws.services.lambda.AWSLambdaAsync; import com.amazonaws.services.lambda.AWSLambdaAsyncClientBuilder; import com.amazonaws.services.lambda.model.InvokeRequest; import com.amazonaws.services.lambda.model.InvokeResult; import com.amazonaws.handlers.AsyncHandler; import java.nio.ByteBuffer; import java.util.concurrent.Future; public class InvokeLambdaFunctionCallback { private class AsyncLambdaHandler implements AsyncHandler<InvokeRequest, InvokeResult> { public void onSuccess(InvokeRequest req, InvokeResult res) { System.out.println("\nLambda function returned:"); ByteBuffer response_payload = res.getPayload(); System.out.println(new String(response_payload.array())); System.exit(0); } public void onError(Exception e) { System.out.println(e.getMessage()); System.exit(1); } } public static void main(String[] args) { String function_name = "HelloFunction"; String function_input = "{\"who\":\"SDK for Java\"}"; AWSLambdaAsync lambda = AWSLambdaAsyncClientBuilder.defaultClient(); InvokeRequest req = new InvokeRequest() .withFunctionName(function_name) .withPayload(ByteBuffer.wrap(function_input.getBytes())); Future<InvokeResult> future_res = lambda.invokeAsync(req, new AsyncLambdaHandler()); System.out.print("Waiting for async callback"); while (!future_res.isDone() && !future_res.isCancelled()) { // perform some other tasks... try { Thread.sleep(1000); } catch (InterruptedException e) { System.err.println("Thread.sleep() was interrupted!"); System.exit(0); } System.out.print("."); } } }

Bonnes pratiques

Exécution des rappels

Votre implémentation de AsyncHandler est exécutée à l'intérieur du groupe de threads dont le client asynchrone est propriétaire. Un code bref, rapidement exécuté est le plus approprié à l'intérieur de votre implémentation d' AsyncHandler. Un code de longue durée ou un code de blocage à l'intérieur des méthodes de votre gestionnaire peuvent entraîner un conflit au sein du groupe de threads utilisé par le client asynchrone et empêcher le client d'exécuter les demandes. Si vous avez une tâche de longue durée qui doit commencer à partir d'un rappel, faites en sorte que le rappel exécute sa tâche dans un nouveau thread ou dans un groupe de threads géré par votre application.

Configuration du groupe de threads

Les clients asynchrones du AWS SDK for Java fournissent un pool de threads par défaut qui devrait fonctionner pour la plupart des applications. Vous pouvez implémenter une personnalisation ExecutorServiceet la transmettre à des clients AWS SDK for Java asynchrones pour mieux contrôler la façon dont les pools de threads sont gérés.

Par exemple, vous pouvez fournir une ExecutorService implémentation qui utilise un paramètre personnalisé ThreadFactorypour contrôler le nom des threads du pool ou pour enregistrer des informations supplémentaires sur l'utilisation des threads.

Accès asynchrone

La TransferManagerclasse du SDK offre un support asynchrone pour travailler avec. Amazon S3TransferManagergère les chargements et téléchargements asynchrones, fournit des rapports d'avancement détaillés sur les transferts et prend en charge les rappels lors de différents événements.