Implementar código antes ou depois dos snapshots da função do Lambda - AWS Lambda

Implementar código antes ou depois dos snapshots da função do Lambda

É possível usar hooks de runtime para implementar o código antes que o Lambda crie um snapshot ou depois que o Lambda retorna uma função de um snapshot. Os hooks de runtime estão disponíveis como parte do projeto de código aberto Coordinated Restore at Checkpoint (CRaC). O CRaC está em desenvolvimento para o Open Java Development Kit (OpenJDK). Para obter um exemplo de como usar o CRaC com uma aplicação de referência, consulte o repositório CRaC no GitHub. O CRaC usa três elementos principais:

  • Resource: uma interface com dois métodos, beforeCheckpoint() e afterRestore(). Use esses métodos para implementar o código deseja executar antes de um snapshot e depois de uma restauração.

  • Context <R extends Resource>: para receber notificações de pontos de verificação e restaurações, Resource deve estar registrado em um Context.

  • Core: o serviço de coordenação, que fornece o padrão global Context por meio do método estático Core.getGlobalContext().

Para obter mais informações sobre Context e Resource, consulte Package org.crac (Pacote org.crac) na documentação do CRaC.

Use as etapas a seguir para implementar os hooks de runtime com o pacote org.crac. O runtime do Lambda contém uma implementação de contexto CRaC personalizada que chama os hooks de runtime antes do ponto de verificação e depois da restauração.

Etapa 1: atualizar a configuração de compilação

Adicione a dependência org.crac à configuração de compilação. O exemplo a seguir usa o Gradle. Para obter exemplos de outros sistemas de compilação, consulte a documentação do Apache Maven.

dependencies { compile group: 'com.amazonaws', name: 'aws-lambda-java-core', version: '1.2.1' # All other project dependecies go here: # ... # Then, add the org.crac dependency: implementation group: 'org.crac', name: 'crac', version: '1.4.0' }

Etapa 2: atualizar o manipulador do Lambda

O manipulador da função do Lambda é o método no código da função que processa eventos. Quando sua função é invocada, o Lambda executa o método do manipulador. A função é executada até que o manipulador retorne uma resposta, seja encerrado ou atinja o tempo limite.

Para ter mais informações, consulte Definir o manipulador da função do Lambda em Java.

O manipulador exemplificado a seguir mostra como executar o código antes do ponto de verificação (beforeCheckpoint()) e depois da restauração (afterRestore()). Esse manipulador também registra o Resource no Context global gerenciado pelo runtime.

nota

Quando o Lambda cria um snapshot, o código de inicialização pode ser executado por até 15 minutos. O limite de tempo é de 130 segundos ou o tempo limite da função configurada (máximo de 900 segundos), o que for maior. Seus hooks de runtime de beforeCheckpoint() contam até o limite de tempo do código de inicialização. Quando o Lambda restaura um snapshot, o runtime (JVM) deve ser carregado e os hooks de runtime afterRestore() devem ser concluídos dentro do limite de tempo-limite (dez segundos). Caso contrário, você obterá uma SnapStartTimeoutException.

... import org.crac.Resource; import org.crac.Core; ... public class CRaCDemo implements RequestStreamHandler, Resource { public CRaCDemo() { Core.getGlobalContext().register(this); } public String handleRequest(String name, Context context) throws IOException { System.out.println("Handler execution"); return "Hello " + name; } @Override public void beforeCheckpoint(org.crac.Context<? extends Resource> context) throws Exception { System.out.println("Before checkpoint"); } @Override public void afterRestore(org.crac.Context<? extends Resource> context) throws Exception { System.out.println("After restore");

Context mantém somente uma WeakReference para o objeto registrado. Se um Resource estiver na coleta de resíduos, os hooks de runtime não serão executados. O código deve manter uma referência forte para o Resource com a finalidade de garantir que o hook de runtime seja executado.

Veja a seguir dois exemplos de padrões a serem evitados:

exemplo : objeto sem uma referência forte
Core.getGlobalContext().register( new MyResource() );
exemplo : objetos de classes anônimas
Core.getGlobalContext().register( new Resource() { @Override public void afterRestore(Context<? extends Resource> context) throws Exception { // ... } @Override public void beforeCheckpoint(Context<? extends Resource> context) throws Exception { // ... } } );

Em vez disso, mantenha uma referência forte. No exemplo a seguir, o recurso registrado não está na coleta de resíduos e os hooks de runtime são executados de forma consistente.

exemplo : objeto com uma referência forte
Resource myResource = new MyResource(); // This reference must be maintained to prevent the registered resource from being garbage collected Core.getGlobalContext().register( myResource );