Programação assíncrona - AWS SDK for Java 1.x

Anunciamos o próximo end-of-support para AWS SDK for Java (v1). Recomendamos migrar para o AWS SDK for Java v2. Para saber as datas e receber detalhes adicionais e informações sobre como migrar, consulte o anúncio vinculado.

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Programação assíncrona

Você pode usar métodos síncronos ou assíncronos para chamar operações em serviços. AWS Os métodos síncronos bloqueiam a execução do seu thread até o cliente receber uma resposta do serviço. Os métodos assíncronos retornam imediatamente, devolvendo o controle ao thread de chamada sem aguardar uma resposta.

Como um método assíncrono retorna antes de uma resposta estar disponível, você precisa de uma maneira de obter a resposta quando ela estiver pronta. O AWS SDK for Java fornece duas formas: objetos futuros e métodos de retorno de chamada.

Futures do Java

Os métodos assíncronos AWS SDK for Java retornam um objeto Future que contém os resultados da operação assíncrona no futuro.

Chame o método Future isDone() para ver se o serviço já forneceu um objeto de resposta. Quando a resposta estiver pronta, você poderá obter o objeto de resposta chamando o método Future get(). É possível usar esse mecanismo para sondar periodicamente os resultados da operação assíncrona, enquanto o aplicativo continua funcionando em outras atividades.

Aqui está um exemplo de uma operação assíncrona que chama uma Lambda função, recebendo uma Future que pode conter um objeto. InvokeResult O objeto InvokeResult será recuperado somente depois que isDone() for 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); } }

Retornos de chamada assíncronos

Além de usar o Future objeto Java para monitorar o status das solicitações assíncronas, o SDK também permite que você implemente uma classe que usa a interface. AsyncHandler AsyncHandlerfornece dois métodos que são chamados dependendo de como a solicitação foi concluída: onSuccess onError e.

A principal vantagem da interface da abordagem de interface do retorno de chamada é que ela evita a necessidade de sondar o objeto Future para descobrir quando a requisição foi concluída. Em vez disso, o código pode iniciar imediatamente a próxima atividade e contar com o SDK para chamar o handler no momento certo.

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

Práticas recomendadas

Execução do retorno de chamada

A implementação de AsyncHandler é executada dentro do grupo de threads de propriedade do cliente assíncrono. Resumidamente, o código executado rapidamente é mais apropriado dentro da implementação AsyncHandler. Executar por muito tempo ou bloquear código dentro dos métodos handler pode causar contenção do grupo de threads usado pelo cliente assíncrono e evitar que o cliente execute requisições. Se você tiver uma tarefa de longa duração que precise começar de um retorno de chamada, o retorno de chamada deverá executar a tarefa em um novo thread ou em um grupo de threads gerenciado pelo aplicativo.

Configuração do grupo de threads

Os clientes assíncronos no AWS SDK for Java fornecem um pool de threads padrão que deve funcionar para a maioria dos aplicativos. Você pode implementar um personalizado ExecutorServicee passá-lo para clientes AWS SDK for Java assíncronos para ter mais controle sobre como os grupos de threads são gerenciados.

Por exemplo, você pode fornecer uma ExecutorService implementação que usa um personalizado ThreadFactorypara controlar como os encadeamentos no pool são nomeados ou para registrar informações adicionais sobre o uso do encadeamento.

Processo assíncrono

A TransferManagerclasse no SDK oferece suporte assíncrono para trabalhar com. Amazon S3TransferManagergerencia uploads e downloads assíncronos, fornece relatórios detalhados sobre o progresso das transferências e oferece suporte a retornos de chamada em diferentes eventos.