Skip to content

bug(db-migrator): Lambda のウォーム再利用時、初回呼び出し後にクローズ済みの DSQL プールが返る #219

Description

@konokenj

キットのバージョン / コミット

dev/v3 @ e3a3954

期待される挙動

DSQL マイグレータの Lambda ハンドラは、リトライやウォームな実行環境での再呼び出しを含め、毎回の呼び出しで正常に機能するデータベース接続を取得できるべきである。

実際の挙動

packages/db/src/client.ts は単一の AuroraDSQLPool をモジュールスコープでキャッシュしている。apps/db-migrator/src/handler.ts はそのシングルトンを取得し、finally 節で無条件に await pool.end() を呼ぶ。同一 Lambda 実行環境での 2 回目の呼び出し(リトライ、手動 invoke、あるいはウォームなサンドボックスの後続再利用)では、getPool() が既に終了済みのプールを返す。終了済みの node-postgres プールは新規接続を受け付けられないため、2 回目の呼び出しはマイグレーションが評価される前に失敗する。

問題が発生する条件

  • マイグレータ Lambda が少なくとも 1 回呼び出されて完了している(成功・失敗を問わない)
  • その後 AWS Lambda がウォームな実行環境を後続の呼び出しに再利用する(一時的失敗後のリトライ、またはマイグレーション再実行のための手動 invoke)

再現手順

  1. dev/v3 をデプロイする
  2. 短時間のうちに DSQL マイグレータのハンドラを 2 回トリガーする(Custom Resource トリガーを強制的に再実行させる、または Lambda を手動で invoke する)
  3. 2 回目の呼び出しが接続取得の時点でエラーになることを観測する

分析と修正案(任意)

根本原因: シングルトンのプールキャッシュが pool.end() 後に無効化されない。選択肢:

  • 再利用可能なプールをハンドラ呼び出し間で保持する(pool.end() を呼ばない)
  • プール終了時にモジュールレベルのキャッシュをクリアし、次回呼び出しで新しいプールを再構築する

回帰テスト: 単一の Node ランタイムインスタンス内でハンドラを 2 回呼び出し、両方が接続を取得できることをアサートする。v3 差分レビュー(executor 06 の発見 F-DB-01)で発見。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingneeds-triageAwaiting maintainer review and classification

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions