

# Lambda マネージドインスタンスの Rust サポート
<a name="lambda-managed-instances-rust"></a>

## 同時実行数の設定
<a name="lambda-managed-instances-rust-concurrency-config"></a>

Lambda が各実行環境に送信する同時リクエストの最大数は、関数設定の `PerExecutionEnvironmentMaxConcurrency` 設定で制御できます。これはオプション設定です。Rust のデフォルト値は vCPU ごとに 8 つの同時リクエストですが、独自の値を設定することも可能です。この値は、ランタイムによってスポーンされた Tokio タスクの数を決定するもので、実行環境の存続期間中は固定 (静的) となります。各ワーカーは実行中のリクエストを 1 つだけ処理し、多重処理することはありません。Lambda は、各実行環境の容量に応じて、設定された最大数までの同時リクエストの数を自動的に調整し、それらのリクエストを取得します。

## 同時実行のための関数の構築
<a name="lambda-managed-instances-rust-building"></a>

Lambda マネージドインスタンスを使用する場合は、他のマルチスレッド環境と同じスレッドセーフな環境を適用する必要があります。ハンドラーオブジェクトはすべてのワーカースレッドで共有されるため、ミュータブルな状態はスレッドセーフである必要があります。これには、コレクション、データベース接続、およびリクエスト処理中に変更される静的オブジェクトが含まれます。

同時リクエスト処理を有効にするには、 `concurrency-tokio` 機能フラグを `Cargo.toml` ファイルに追加します。

```
[dependencies]  
lambda_runtime = { version = "1", features = ["concurrency-tokio"] }
```

`lambda_runtime::run_concurrent(…)` エントリポイントは、通常メイン関数の `#[tokio::main]` 属性によって提供される Tokio ランタイム内から呼び出す必要があります。ハンドラークロージャは [https://doc.rust-lang.org/std/clone/trait.Clone.html](https://doc.rust-lang.org/std/clone/trait.Clone.html) \$1 [https://doc.rust-lang.org/std/marker/trait.Send.html](https://doc.rust-lang.org/std/marker/trait.Send.html) を実装する必要があります。これにより、フレームワークは複数の非同期タスク間でハンドラーを安全に共有できます。これらの境界が満たされない場合、コードはコンパイルエラーになります。

呼び出し間で共有される状態 (データベース接続プールや設定構造体など) が必要な場合は、それを [https://doc.rust-lang.org/std/sync/struct.Arc.html](https://doc.rust-lang.org/std/sync/struct.Arc.html) で包み、各呼び出しごとにその `Arc` をクローンします。

すべての AWS SDK for Rust クライアントは同時実行セーフであり、特別な処理は必要ありません。

### 例: AWS SDK クライアント
<a name="lambda-managed-instances-rust-example-sdk"></a>

次の例では、S3 クライアントを使用して、呼び出しごとにオブジェクトをアップロードします。クライアントは、`Arc` を介さず、直接クロージャ内へクローンされます。

```
let config = aws_config::load_defaults(BehaviorVersion::latest()).await;  
let s3_client = aws_sdk_s3::Client::new(&config);  
  
run_concurrent(service_fn(move |event: LambdaEvent<Request>| {  
    let s3_client = s3_client.clone(); // cheap clone, no Arc needed  
    async move {  
        s3_client.put_object()  
            .bucket(&event.payload.bucket)  
            .key(&event.payload.key)  
            .body(event.payload.body.into_bytes().into())  
            .send()  
            .await?;  
        Ok(Response { message: "uploaded".into() })  
    }  
}))  
.await
```

### 例: データベース接続プール
<a name="lambda-managed-instances-rust-example-db"></a>

クライアントや設定などの共有状態にハンドラからアクセスする必要がある場合は、それらを [https://doc.rust-lang.org/std/sync/struct.Arc.html](https://doc.rust-lang.org/std/sync/struct.Arc.html) で包み、各呼び出しごとにその `Arc` をクローンします。

```
#[derive(Debug)]  
struct AppState {  
    dynamodb_client: DynamoDbClient,  
    table_name: String,  
    cache_ttl: Duration,  
}  
  
let config = aws_config::load_defaults(BehaviorVersion::latest()).await;  
let state = Arc::new(AppState {  
    dynamodb_client: DynamoDbClient::new(&config),  
    table_name: std::env::var("TABLE_NAME").expect("TABLE_NAME must be set"),  
    cache_ttl: Duration::from_secs(300),  
});  
  
run_concurrent(service_fn(move |event: LambdaEvent<Request>| {  
    let state = state.clone();  
    async move { handle(event, state).await }  
}))  
.await
```

## 共有の /tmp ディレクトリ
<a name="lambda-managed-instances-rust-tmp"></a>

`/tmp` ディレクトリは、実行環境内のすべての同時呼び出し間で共有されます。呼び出しごとに一意のファイル名 (例えばリクエスト ID を含める) を使用するか、明示的なファイルロックを実装してデータの破損を回避します。

## ログ記録
<a name="lambda-managed-instances-rust-logging"></a>

ログインターリービング (ログでインターリーブされるさまざまなリクエストからのログエントリ) は、複数同時実行システムでは正常です。Lambda マネージドインスタンスを使用する関数は、Lambda の[高度なログ記録コントロール](monitoring-logs.md#monitoring-cloudwatchlogs-advanced)を通じて、構造化された JSON ログ形式をサポートします。この形式には `requestId` が含まれ、ログエントリを 1 つのリクエストに関連付けることができます。詳細については、「[トレーシングクレートによる高度なログ記録機能の実装](rust-logging.md#rust-logging-tracing)」を参照してください。

## リクエストコンテキスト
<a name="lambda-managed-instances-rust-context"></a>

`Context` オブジェクトは各ハンドラー呼び出しに直接渡されます。`event.context.request_id` を使用して、現在のリクエストのリクエスト ID にアクセスします。

`event.context.xray_trace_id` を使用して X-Ray トレース ID にアクセスします。Lambda は、Lambda マネージドインスタンスの `_X_AMZN_TRACE_ID` 環境変数をサポートしていません。AWS SDK for Rust を使用すると、X-Ray トレース ID が自動的に伝播されます。

`event.context.deadline` を使用してタイムアウトを検出します。これには、呼び出しの期限がミリ秒単位で含まれます。

## 初期化とシャットダウン
<a name="lambda-managed-instances-rust-lifecycle"></a>

関数の初期化は、実行環境ごとに 1 回行われます。初期化中に作成されたオブジェクトは、リクエスト間で共有されます。

拡張機能を持つ Lambda 関数の場合、実行環境はシャットダウン中に SIGTERM シグナルを出力します。このシグナルは、バッファのフラッシュなどのクリーンアップタスクをトリガーするために拡張機能で使用されます。 `lambda_runtime` は、グレースフルシャットダウンのシグナル処理の設定を簡略化するヘルパー関数 [https://docs.rs/lambda_runtime/latest/lambda_runtime/fn.spawn_graceful_shutdown_handler.html](https://docs.rs/lambda_runtime/latest/lambda_runtime/fn.spawn_graceful_shutdown_handler.html) を提供しています。実行環境のライフサイクルの詳細については、「[Lambda 実行環境のライフサイクルの概要](lambda-runtime-environment.md)」を参照してください。

## 依存関係バージョン
<a name="lambda-managed-instances-rust-dependencies"></a>

Lambda マネージドインスタンスには、以下のパッケージバージョンの最小要件が必要です。
+ `lambda_runtime`: バージョン 1.1.1 以降 (`concurrency-tokio` 機能が有効であること)
+ 最小サポート Rust バージョン (MSRV) は 1.84.0 です。