Programmazione asincrona - AWS SDK for Java 1.x

Abbiamo annunciato l'imminente versione end-of-support di AWS SDK for Java (v1). Ti consigliamo di migrare alla AWS SDK for Java v2. Per date, dettagli aggiuntivi e informazioni su come effettuare la migrazione, consulta l'annuncio collegato.

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Programmazione asincrona

È possibile utilizzare metodi sincroni o asincroni per richiamare le operazioni sui servizi. AWS I metodi sincroni bloccano l'esecuzione del thread finché il client non riceve una risposta dal servizio. I metodi asincroni terminano immediatamente, riassegnando il controllo al thread chiamante senza attendere una risposta.

Poiché un metodo asincrono termina prima che sia disponibile una risposta, occorre un modo per ottenere la risposta quando è pronta. AWS SDK for Java Fornisce due modi: oggetti futuri e metodi di callback.

Java Futures

I metodi asincroni AWS SDK for Java restituiscono un oggetto Future che contiene i risultati dell'operazione asincrona in futuro.

Chiamate il Future isDone() metodo per vedere se il servizio ha già fornito un oggetto di risposta. Quando la risposta è pronta, è possibile ottenere l'oggetto di risposta chiamando il Future get() metodo. È possibile utilizzare questo meccanismo per verificare periodicamente i risultati dell'operazione asincrona mentre l'applicazione continua a lavorare su altre cose.

Ecco un esempio di operazione asincrona che chiama una Lambda funzione, ricevendo un oggetto che può contenere un oggetto. Future InvokeResult L'InvokeResultoggetto viene recuperato solo dopo is. isDone() 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); } }

Chiamate asincrone

Oltre a utilizzare l'Futureoggetto Java per monitorare lo stato delle richieste asincrone, l'SDK consente anche di implementare una classe che utilizza l'interfaccia. AsyncHandler AsyncHandlerfornisce due metodi che vengono chiamati a seconda del modo in cui la richiesta è stata completata: e. onSuccess onError

Il vantaggio principale dell'approccio dell'interfaccia di callback è che vi evita di dover interrogare l'Futureoggetto per scoprire quando la richiesta è stata completata. Al contrario, il codice può iniziare immediatamente la sua attività successiva e fare affidamento sull'SDK per chiamare il gestore al momento giusto.

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("."); } } }

Best practice

Esecuzione del callback

L'implementazione di AsyncHandler viene eseguita all'interno del pool di thread di proprietà del client asincrono. Il codice breve ed eseguito rapidamente è il più appropriato all'interno dell'implementazione. AsyncHandler Il codice a esecuzione prolungata o che blocca i metodi di gestione può causare conflitti per il pool di thread utilizzato dal client asincrono e impedire al client di eseguire le richieste. Se hai un'attività di lunga durata che deve iniziare da un callback, chiedi al callback di eseguire la sua attività in un nuovo thread o in un pool di thread gestito dall'applicazione.

Configurazione del pool di thread

I client asincroni inclusi in AWS SDK for Java forniscono un pool di thread predefinito che dovrebbe funzionare per la maggior parte delle applicazioni. È possibile implementare un file personalizzato ExecutorServicee passarlo a client AWS SDK for Java asincroni per un maggiore controllo sulla gestione dei pool di thread.

Ad esempio, è possibile fornire un'ExecutorServiceimplementazione che utilizzi un'impostazione personalizzata ThreadFactoryper controllare il modo in cui vengono denominati i thread nel pool o per registrare informazioni aggiuntive sull'utilizzo dei thread.

Accesso asincrono

La TransferManagerclasse dell'SDK offre supporto asincrono con cui lavorare. Amazon S3TransferManagergestisce caricamenti e download asincroni, fornisce report dettagliati sullo stato di avanzamento dei trasferimenti e supporta i callback in diversi eventi.