

# Implementar código antes ou depois dos snapshots da função do Lambda
<a name="snapstart-runtime-hooks"></a>

É 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 são úteis para diversas finalidades, como:
+ **Limpeza e inicialização:** antes de criar um snapshot, você pode usar um hook de runtime para realizar operações de limpeza ou liberação de recursos. Depois que um snapshot é restaurado, você pode usar um hook de runtime para reinicializar quaisquer recursos ou estados que não foram capturados no snapshot.
+ **Configuração dinâmica:** você pode usar hooks de runtime para atualizar dinamicamente a configuração ou outros metadados antes que um snapshot seja criado ou depois de restaurado. Isso pode ser útil se sua função precisar se adaptar a mudanças no ambiente de runtime.
+ **Integrações externas:** você pode usar hooks de runtime para integrar-se a serviços ou sistemas externos, como enviar notificações ou atualizar estados externos, como parte do processo de verificação e restauração.
+ **Ajuste de performance:** você pode usar hooks de runtime para ajustar a sequência de startup da função, por exemplo, fazendo o carregamento de dependências previamente. Para ter mais informações, consulte [Ajuste de performance](snapstart-best-practices.md#snapstart-tuning).

As páginas a seguir explicam como implementar hooks de runtime para seu runtime preferido.

**Topics**
+ [Java](snapstart-runtime-hooks-java.md)
+ [Python](snapstart-runtime-hooks-python.md)
+ [.NET](snapstart-runtime-hooks-dotnet.md)

# Hooks de runtime do Lambda SnapStart para Java
<a name="snapstart-runtime-hooks-java"></a>

É 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)](https://wiki.openjdk.org/display/crac). Para obter um exemplo de como usar o CRaC com uma aplicação de referência, consulte o repositório [CRaC](https://github.com/CRaC/docs/blob/master/STEP-BY-STEP.md) 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](https://javadoc.io/doc/io.github.crac/org-crac/latest/index.html) (Pacote org.crac) na documentação do CRaC.

Use as etapas a seguir para implementar os hooks de runtime com o [pacote org.crac](https://github.com/CRaC/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.

## Registro e execução do hook de runtime
<a name="runtime-hooks-registration-java"></a>

A ordem em que o Lambda executa seus hooks de runtime é determinada pela ordem de registro. A ordem de registro segue a ordem de importação, definição ou execução em seu código.
+ `beforeCheckpoint()`: executado na ordem inversa do registro
+ `afterRestore()`: executado na ordem de registro

Certifique-se de que todos os hooks registrados sejam importados e incluídos corretamente no código da sua função. Se você registrar hooks de runtime em um arquivo ou módulo separado, o módulo deverá ser importado, seja diretamente ou como parte de um pacote maior, no arquivo do manipulador da sua função. Se o arquivo ou módulo não for importado no manipulador da função, o Lambda vai ignorar os hooks de 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](configuration-timeout.md) (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 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.

## Etapa 1: atualizar a configuração de compilação
<a name="runtime-hooks-java-update-build"></a>

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](https://search.maven.org/artifact/io.github.crac/org-crac/0.1.3/jar).

```
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
<a name="runtime-hooks-java-update-handler"></a>

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 obter mais informações, consulte [Definir o manipulador da função do Lambda em Java](java-handler.md).

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](configuration-timeout.md) (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 [https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ref/WeakReference.html](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ref/WeakReference.html) para o objeto registrado. Se um [https://javadoc.io/static/io.github.crac/org-crac/0.1.3/org/crac/Resource.html](https://javadoc.io/static/io.github.crac/org-crac/0.1.3/org/crac/Resource.html) 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:

**Example : objeto sem uma referência forte**  

```
Core.getGlobalContext().register( new MyResource() );
```

**Example : 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.

**Example : 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 );
```

# Hooks de runtime do Lambda SnapStart para Python
<a name="snapstart-runtime-hooks-python"></a>

É 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 do Python estão disponíveis como parte da biblioteca de código aberto [Snapshot Restore for Python](https://pypi.org/project/snapshot-restore-py/), que está incluída nos runtimes gerenciados do Python. Essa biblioteca fornece dois decoradores que você pode usar para definir seus hooks de runtime:
+ `@register_before_snapshot`: para funções que você deseja executar antes de o Lambda criar um snapshot.
+ `@register_after_restore`: para funções que você deseja executar quando o Lambda retoma uma função de um snapshot.

Como alternativa, você pode usar os seguintes métodos para registrar objetos que podem ser chamados em hooks de runtime:
+ `register_before_snapshot(func, *args, **kwargs)`
+ `register_after_restore(func, *args, **kwargs)`

## Registro e execução do hook de runtime
<a name="runtime-hooks-registration-python"></a>

A ordem em que o Lambda executa seus hooks de runtime é determinada pela ordem de registro:
+ Antes do snapshot: executado na ordem inversa do registro
+ Após o snapshot: executado na ordem de registro

A ordem do registro de hooks de runtime depende de como você define os hooks. Ao usar decoradores (`@register_before_snapshot` e `@register_after_restore`), a ordem de registro segue a ordem de importação, definição ou execução em seu código. Se você precisar de mais controle sobre a ordem de registro, use os métodos `register_before_snapshot()` e `register_after_restore()`, em vez de decoradores.

Certifique-se de que todos os hooks registrados sejam importados e incluídos corretamente no código da sua função. Se você registrar hooks de runtime em um arquivo ou módulo separado, deverá garantir que o módulo seja importado, diretamente ou como parte de um pacote maior, no arquivo do manipulador da sua função. Se o arquivo ou módulo não for importado no manipulador da função, o Lambda vai ignorar os hooks de 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](configuration-timeout.md) (máximo de 900 segundos), o que for maior. Seus hooks de runtime de `@register_before_snapshot` contam até o limite de tempo do código de inicialização. Quando o Lambda restaura um snapshot, o runtime deve ser carregado e os hooks de runtime `@register_after_restore` devem ser concluídos dentro do limite de tempo limite (dez segundos). Caso contrário, você obterá uma SnapStartTimeoutException.

## Exemplo
<a name="runtime-hooks-python-code-sample"></a>

O manipulador exemplificado a seguir mostra como executar o código antes do ponto de verificação (`@register_before_snapshot`) e depois da restauração (`@register_after_restore`).

```
from snapshot_restore_py import register_before_snapshot, register_after_restore

def lambda_handler(event, context):
    # Handler code

@register_before_snapshot
def before_checkpoint():
    # Logic to be executed before taking snapshots

@register_after_restore
def after_restore():
    # Logic to be executed after restore
```

Para conferir mais exemplos, consulte [Snapshot Restore for Python](https://github.com/aws/snapshot-restore-py/tree/main/examples) no repositório do GitHub da AWS.

# Hooks de runtime do Lambda SnapStart para .NET
<a name="snapstart-runtime-hooks-dotnet"></a>

É 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 do.NET estão disponíveis como parte do pacote [Amazon.Lambda.Core](https://www.nuget.org/packages/Amazon.Lambda.Core) (versão 2.5.0 ou posterior). Essa biblioteca fornece dois métodos que você pode usar para definir seus hooks de runtime:
+ `RegisterBeforeSnapshot()`: código a ser executado antes da criação do snapshot
+ `RegisterAfterSnapshot()`: código a ser executado após retomar uma função de um snapshot

**nota**  
Se você estiver usando a [estrutura Lambda Annotations para .NET](csharp-handler.md#csharp-handler-annotations), atualize para [Amazon.Lambda.Annotations](https://www.nuget.org/packages/Amazon.Lambda.Annotations) versão 1.6.0 ou posterior para garantir a compatibilidade com o SnapStart.

## Registro e execução do hook de runtime
<a name="runtime-hooks-registration-dotnet"></a>

Registre seus hooks no código de inicialização. Considere as seguintes diretrizes com base no [modelo de execução](csharp-handler.md#csharp-handler-setup) da função do Lambda:
+ Para a [abordagem de assembly executável](csharp-handler.md#csharp-executable-assembly-handlers), registre seus hooks antes de iniciar o bootstrap do Lambda com `RunAsync`.
+ Para a [abordagem de bibliotecas de classes](csharp-handler.md#csharp-class-library-handlers), registre seus hooks no construtor de classe do manipulador.
+ Para [aplicações ASP.NET Core](csharp-package-asp.md), registre seus hooks antes de chamar o método `WebApplications.Run`.

Para registrar hooks de runtime para o SnapStart no .NET, use os seguintes métodos:

```
Amazon.Lambda.Core.SnapshotRestore.RegisterBeforeSnapshot(BeforeCheckpoint);
Amazon.Lambda.Core.SnapshotRestore.RegisterAfterRestore(AfterCheckpoint);
```

Quando vários tipos de hooks são registrados, a ordem em que o Lambda executa seus hooks de runtime é definida pela ordem de registro:
+ `RegisterBeforeSnapshot()`: executado na ordem inversa do registro
+ `RegisterAfterSnapshot()`: executado na ordem de registro

**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](configuration-timeout.md) (máximo de 900 segundos), o que for maior. Seus hooks de runtime de `RegisterBeforeSnapshot()` contam até o limite de tempo do código de inicialização. Quando o Lambda restaura um snapshot, o runtime deve ser carregado e os hooks de runtime `RegisterAfterSnapshot()` devem ser concluídos dentro do limite de tempo limite (dez segundos). Caso contrário, você obterá uma SnapStartTimeoutException.

## Exemplo
<a name="runtime-hooks-dotnet-code-sample"></a>

A função exemplificada a seguir mostra como executar o código antes do ponto de verificação (`RegisterBeforeSnapshot`) e depois da restauração (`RegisterAfterRestore`).

```
public class SampleClass
{
    public SampleClass()
    {
        Amazon.Lambda.Core.SnapshotRestore.RegisterBeforeSnapshot(BeforeCheckpoint);
        Amazon.Lambda.Core.SnapshotRestore.RegisterAfterRestore(AfterCheckpoint);
    }

    private ValueTask BeforeCheckpoint()
    {
        // Add logic to be executed before taking the snapshot
        return ValueTask.CompletedTask;
    }

    private ValueTask AfterCheckpoint()
    {
        // Add logic to be executed after restoring the snapshot
        return ValueTask.CompletedTask;
    }

    public APIGatewayProxyResponse FunctionHandler(APIGatewayProxyRequest request, ILambdaContext context)
    {
        // Add business logic

        return new APIGatewayProxyResponse
        {
            StatusCode = 200
        };
    }
}
```