Sledge は、2003年に Livin' On The EDGE が公開した Perl 製の Web アプリケーションフレームワークです。mod_perl 1.x の上で動き、ドキュメントは EUC-JP で書かれています。GitHub に移されて眠っていたこのリポジトリを、Ubuntu 26.04 と Perl 5.44 の上で起こし、Kubernetes で運用できるところまで持っていきました。作業は AI と一緒に進めています。やったことを順に書きます。
Perl 5.44 で動かす
Ubuntu 26.04 の標準の perl は 5.40 なので、Perl 5.44.0 をソースからビルドする Dockerfile を用意しました。
既存のテストを流すと、48ファイル中7ファイルが落ちました。原因は Digest::SHA1 や UNIVERSAL::require への依存、Class::Trigger の内部構造の変化、UTF-8 の二重エンコードなどです。
Makefile.PL も、Perl 5.26 で @INC から . が消えた影響で動かなくなっていました。
mod_perl をやめて PSGI で動かす
mod_perl 1.x は今の Perl では(頑張らないと)動かないので、Sledge::Pages::PSGI を追加して Starlet で配信するようにしました。
既存コードには %ENV を直接読む箇所が多いため、リクエストの間だけ CGI 互換の環境変数を用意しています。
既存のアプリは、基底クラスを差し替えるだけで PSGI アプリになります。
コンテナと Kubernetes に載せる
開発用と本番用のイメージを1つの Dockerfile から作り、本番用は非 root で動かします。 Kubernetes のマニフェストには probe と preStop を入れ、Starlet が処理中のリクエストを終えてから止まるようにしました。 kind 上でローリングアップデートを試したところ、9,783 リクエストがすべて 200 で返りました。
セッションを今の水準に合わせる
セッション ID は時刻と rand() から作られていて、推測される恐れがありました。OS の乱数源から作るように変えています。
保存形式は Storable から JSON に変え、Cookie には HttpOnly と SameSite=Lax を既定で付けます。
保存先には Valkey と暗号化 Cookie を足し、Pod をいくつ並べてもセッションを共有できるようにしました。
設定は環境変数から読む
Sledge::Config::Env を作り、ConfigMap と Secret をそのまま設定として読めるようにしました。必須の項目が欠けていれば起動時に落ちます。
ハマったのは Service リンクでした。sledge-ws という Service を作ると SLEDGE_WS_PORT=tcp://... が勝手に注入され、設定名とぶつかりました。
enableServiceLinks: false で止めています。
ログは JSON で出す
Sledge::Logger で、1行1 JSON のログを標準エラー出力に書くようにしました。
リクエスト ID を前段から引き継ぎ、アクセスログにもアプリのログにも付けます。
処理されなかった例外はログに残し、利用者には詳細を見せずに 500 を返します。
OpenTelemetry で計装する
Perl SDK 標準の BatchSpanProcessor は、IO::Async のイベントループでスパンを送ります。prefork の Starlet ではこのループが回らないので、スパンは一つも届きませんでした。 そこで、レスポンスを返し終えた後に同期的に送るプロセッサーを自作しています。 kind で動かすと、アイドル中のワーカーにスパンが残り続ける問題も見つかり、リクエストごとに送る設定を既定にしました。
WebSocket を足す
Starlet では1本の接続が1つのワーカーを占有するので、WebSocket は Mojolicious で作った別プロセスで受けます。セッションとログ、トレースは Sledge と共有しています。 一番時間を使ったのは Mojolicious の癖です。ハンドシェイクが確立する前に送信すると、接続が落ちます。 20クライアントをつないだままサーバーを入れ替えると、全員が 1001 で閉じられて自動で再接続し、取りこぼしは1クライアントあたり最大2件でした。
ドキュメントを英語にする
EUC-JP で書かれていた README や POD を英訳し、新しく英語の README.md を書きました。 英訳の前は、POD の構文チェックが文字コードの問題で通っていませんでした。 日本語が残っているのは、文字化けを確かめるテストデータの2ファイルだけです。
動かしてみて
20年以上前のコードでも、テストが残っていたおかげで、どこが壊れたかをすぐに特定できました。最終的にテストは61ファイル・576件まで増えています。 意外だったのは、ハマった箇所の多くが Sledge の外にあったことです。Mojolicious、OpenTelemetry SDK、Kubernetes と、新しい側の道具の前提でつまずきました。古いコードを今の環境に載せるときは、古い側より新しい側を疑って、挙動を一つずつ実際に確かめるのが近道でした。












