

# コンテナイメージ SnapStart フックの実装
<a name="snapstart-runtime-hooks-custom"></a>

## 概要
<a name="snapstart-custom-overview"></a>

[コンテナイメージ関数](images-create.md)で SnapStart を使用する場合、ランタイムは、関数のライフサイクルを調整し、適切なライフサイクルフェーズ中にスナップショット前と復元後のフックを呼び出す必要があります。これらのフックを使用すると、snapshot-and-restore ライフサイクルの各ポイントでカスタムロジック (認証情報の更新や乱数ジェネレーターの再シードなど) を実行できます。SnapStart がサポートされているマネージドランタイム、またはそれらのランタイムに対応するベースイメージ (Java バージョン 11 以降、Python バージョン 3.12 以降、.NET バージョン 8 以降) を使用する場合、ライフサイクルの調整は Lambda が自動で行います。[Lambda 関数スナップショットの前後のコード実装](snapstart-runtime-hooks.md) で解説されている API を使用ってフックを登録します。

自分のベースコンテナイメージ、Runtime Interface Client (RIC)、または Lambda ベースイメージ (provided.al2023、Node.js、Ruby 用) を使用する場合は、このページに記載した手順に従って SnapStart を使用します。

## 前提条件
<a name="snapstart-custom-prerequisites"></a>

Lambda がスナップショットから関数を復元すると、初期化中に定義されたすべてのステータス (乱数ジェネレーター、一意の ID、キャッシュされた認証情報など) が、そのスナップショットから復元されたすべての実行環境で共有されます。コンテナイメージベースの Lambda 関数で SnapStart を使用するときは、事前に [Lambda SnapStart での一意性の取り扱い](snapstart-uniqueness.md) を読み、「[暗号論的擬似乱数生成器 (CSPRNG) を使用する](https://docs.aws.amazon.com/lambda/latest/dg/snapstart-uniqueness.html#snapstart-csprng)」に記載された要件が満たされていることを確認します。

要件が満たされていることを確認したら、次の 2 つのオプションのうちいずれかを選択します。

1. **オプション 1:** 関数のスナップショットが再開されたときにカスタムロジックを実行するためスナップショット前と復元後のフックが必要な場合は、セクション「[SnapStart ライフサイクルフックの実装](#snapstart-custom-implement)」の手順に従います。

1. **オプション 2:** 上記のフックが必要ない場合は、Dockerfile 内で次のラベルを指定して、このコンテナイメージの SnapStart を有効にします。

```
LABEL com.amazonaws.lambda.feature.snapstart="Allow"
```

このコンテナイメージが `/restore/next` API を実装しておらずラベルも含まれていない場合、バージョンの発行は失敗します。

**注記**  
上記の前提条件は、Java (バージョン 11 以降)、Python (バージョン 3.12 以降)、.NET (バージョン 8 以降) 用の Lambda マネージドベースイメージを使用する場合は不要です。これらは既に SnapStart ライフサイクルを調整し一意性の要件を満たしているためです。

## ライフサイクルの概要
<a name="snapstart-custom-lifecycle"></a>

次の図は、SnapStart カスタムランタイムが実行することが想定されている、Runtime API 呼び出しの順序を示したものです。すべての呼び出しが Runtime API 契約に含まれています。一方、呼び出し \#3、\#4、\#5、\#6 は SnapStart に固有のものです。

![SnapStart カスタムランタイムのランタイム API コールの順序を示すシーケンス図: init、before-snapshot フック、GET /runtime/restore/next、after-restore フック、標準呼び出しループ。](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/images/snapstart-custom-runtime-lifecycle.png)


## SnapStart ライフサイクルフックの実装
<a name="snapstart-custom-implement"></a>

コンテナイメージ関数で SnapStart を使用するには、以下の手順に従います。

1. **before-snapshot フックを実行してスナップショット作成プロセスをトリガーする:** 関数の初期化コードの最後のステップとして、必要に応じて before-snapshot フックを実行し、スナップショット作成プロセスをトリガーします。これらの手順は SnapStart が有効になっている場合にのみ実行します。有効になっているかどうかは、`AWS_LAMBDA_INITIALIZATION_TYPE` 環境変数の値が `snap-start` に設定されているかどうかをみてチェックします。登録済みの before-snapshot フックを実行し、`GET /runtime/restore/next` を呼び出してスナップショット作成プロセスをトリガーします。before-snapshot フックがエラーをスローするか返した場合、ランタイムはエラーを `/runtime/init/error` エンドポイントに送信します。以下の擬似コードを使ったサンプルを参照してください。

   ```
   # After all initialization code has finished:
   
       READ initialization_type FROM environment variable "AWS_LAMBDA_INITIALIZATION_TYPE"
   
       IF initialization_type IS "snap-start" THEN
   
           TRY
               EXECUTE registered before-snapshot hooks
           ON ERROR
               POST error to /runtime/init/error
                   SET header  Lambda-Runtime-Function-Error-Type  TO  <Category>.<Reason>
                   SET body    TO  { errorMessage, errorType, stackTrace }
               EXIT process with non-zero code
   
           # Signal readiness for snapshot
           SEND GET request to /runtime/restore/next
           # The request blocks until Lambda restores the execution environment from the snapshot, then returns HTTP 200.
   
       END IF
   ```
**注記**  
init フェーズと before-snapshot フックは、`max(function_timeout, 130 seconds)` という共通のタイムアウトを共有します。この制限を超えると、Lambda は PublishVersion リクエストに失敗します。また、`/runtime/invocation/next` と同様、`/runtime/restore/next` 呼び出しもブロッキング呼び出しです。Lambda がスナップショットから実行環境を復元するまで処理がブロックされます。

1. **after-restore フックを実行し、呼び出しループに進む。**`GET /runtime/restore/next` が 200 を返すときは、ランタイムは登録済みの after-restore フックを実行してから呼び出しループに進む必要があります。after-restore フックが失敗した場合は、エラーを `/runtime/restore/error` に報告します。after-restore フックが完了したら、`GET /runtime/invocation/next` を呼び出して標準の呼び出しループに入ります。ここからの動作は SnapStart を使用しない関数と同じです。以下の擬似コードを使ったサンプルを参照してください。

   ```
   # After the snapshot has been restored
   # (i.e., GET /runtime/restore/next has returned HTTP 200):
   
       TRY
           EXECUTE registered after-restore hooks
       ON ERROR
           POST error to /runtime/restore/error
               SET header  Lambda-Runtime-Function-Error-Type  TO  <Category>.<Reason>
               SET body    TO  { errorMessage, errorType, stackTrace }
   
   # Proceed to the invoke loop
   ```

## エラー処理
<a name="snapstart-custom-error-handling"></a>

フックが失敗した場合、ランタイムはエラーを適切な API エンドポイントに報告してプロセスを終了する必要があります。以下の表は各段階の動作をまとめたものです。


| フェーズ | エラー API エンドポイント | 失敗した場合の動作 | 
| --- | --- | --- | 
| 初期化/スナップショット前 | POST /runtime/init/error | Lambda は PublishVersion リクエストを失敗させます。プロセスを終了します。 | 
| 復元後 | POST /runtime/restore/error | Lambda は処理中の呼び出しに失敗し、実行環境を破棄します。プロセスを終了します。 | 

両方の API エンドポイントで `Lambda-Runtime-Function-Error-Type` ヘッダーを `<Category.Reason>` 形式の値 (例: `Runtime.BeforeSnapshotError` または `Runtime.AfterRestoreError`) に設定します。`errorMessage`、`errorType`、およびオプションの `stackTrace` を含むエラーの本文を含めます。

API エンドポイントの完全な仕様とレスポンスコードについては、Runtime API リファレンスの「[初期化エラー](runtimes-api.md#runtimes-api-initerror)」と「[復元後 (SnapStart にのみ該当)](runtimes-api.md#runtimes-api-restore-error)」を参照してください。