本文へ移動

AI Buildersのための最新のニュース、知見、事例を毎日お届け

運営会社
AIネイティブ企業の実践

毎晩のE2Eは67秒で終わり、Macは3時間重いままだった

社内の開発機で毎晩走る E2E が 67 秒で終わった後、kernel_task が 8,453MB に膨らみ 3 時間戻らなかった。手元の定期実行を棚卸しし、四つを GitHub Actions へ移した。Actions の分数は既に無料の 3,000 分を超えていたので、移す範囲は費用を見て選んだ。

記事の内容を自社でどう進めるか、内容が固まっていない段階でも相談できます。仕事の相談

毎週 1 回、その週の記事から 5 本と実践の 1 本を選んでメールで届けます。ニュースレターを購読する(無料)

夜の机の上の Mac と、テストの終了後も高いまま続くメモリのグラフ
Created with Grok

社内の開発機A2 (処理役と呼ぶClaude Codeのセッションを並べて動かす16GBのMac) で、毎晩走るE2Eは67秒で終わった。ところが直後にkernel_taskが8,453MBに膨らみ、3時間戻らなかった。同じ夜、手元で走る重いPlaywrightがMacのメモリを圧迫し、新しい処理役を開く門が閉じていた。PRのCIが既に回すE2Eを、手元でも重ねて回していた。同じ夜、もう一台の端末BでもWebKitのテストの後にkernel_taskが19,456MBに達した。私は手元の定期実行を四つともGitHub Actionsへ移す案を選んだ。移した後の夜の結果は、この記録にはまだ無い。

処理役が開けず夜の作業が細った

深夜、A2の門はメモリの段階2で閉じた。門は、新しい処理役を開く前にメモリと負荷を見て、新規の起動だけを止める仕組みである。閉じた時に一番メモリを使っていたのは、手元で試遊 (weekly:playtest) を31分流していた処理役だった。試遊は、製品を画面から操作して確かめる長い検査で、ブラウザはWebKitを使う。

同じ時刻、端末Bも上限の本数まで埋まっていた。記録の時刻表には、A2はメモリの段階2で閉じ、依頼が2件、28分待っていたとある。そこへ毎晩のE2Eが走り、kernel_taskの膨らみが数時間残った。

重ねて回す意味も薄かった。kanji (社内の製品の一つ) のmainに入る変更は、全部PRのe2e.ymlを通る。こちらはubuntuのWebKitで同じ全件を8〜10分かけて回している。毎晩の手元のE2Eは、検査としてはCIと同じ物を二度回していた。どれだけの依頼が待たされたかを、この件だけに切り分けた数字は無い。

規約はあり、定期実行が残っていた

手元で全件のテストやE2Eを流さないという規約は、既にあった。処理役は手元で全件とE2Eを流さずCIに任せる、E2Eはmerge後のmainで回す、の二つである。それでもMacの定期実行と試遊は手元に残っていた。

処理役がA2のlaunchdとcronを全部読んで一覧にすると、Playwrightやブラウザを使う定期実行が並んだ。kanjiの毎晩のE2Eは、WebKitでiPadなど6種の画面を120件回す。テストは短く終わるが、WebKitのプロセスが953MBを使い、直後にkernel_taskが4,843MBから8,453MBへ増えた。週に一度の試遊は40分かかり、nodeが計約1.9GBを使った。Weekend Outing (社内の別の製品) の毎晩の評価とテストは数分で、メモリの上位には出なかった。端末Bの定期実行にPlaywright系は0件で、BのWebKitは処理役が自分で流したe2eだった。

原因の見立ては一度外れた。最初の仮説は、テストの後にWebKitの子のプロセスが孤児として残り、そのGPUのメモリがkernel_taskに数えられた、というもので、確信度は60だった。A2で再現すると違った。画面が消えている間にWebKitが描くとkernel_taskが膨らみ、画面を点ければ5秒で戻る。

さらに、門を閉じた主因もkernel_taskではなかった。A2が段階2で閉じたのは、膨らむ前の深夜と、戻った後の朝である。Bはkernel_taskが19GBに膨らんでいる間も、メモリの空きが63〜68% あった。記録には、主因は「手元で走る重いPlaywright」(確信度70) とある。私が注目したのは、テストの所要時間とログだけを見ていると、この負荷が見えないことだ。67秒で終わったテストの跡が、3時間残っていた。

定期実行を四つActionsへ移した

移す前に、課題の前提が一つ崩れた。最初の制約はActionsの無料枠の中で回すことだったが、組織のActions (Linux) は11月に既に10,591分を使い、無料の3,000分を超えていた。移すほど費用が増えるので、処理役は範囲を三択で聞いた。四つとも移す (月に約885分の増)、WebKitの二つだけ移す (月に約465分の増)、費用を増やさない、の三つである。私は四つとも移す案を選んだ。答えるまでの間、処理役はkanjiの毎晩のE2Eだけを先に止めた。記録には、mainに入る変更は全部PRのe2e.ymlを通るので検査の抜けは無い、とある。

移した先は各製品のリポジトリのworkflowで、scheduleで毎晩か毎週起きる。kanjiは毎晩のE2Eと週の試遊、Weekend Outingは毎晩の評価と毎晩のテストである。結果をLinearのissueにコメントで書く形は前と同じにし、書き手の印だけを [Actions] にした。a2-ops#1140でlaunchdの配布物を四つ消し、A2の設定ファイルは退避してから消した。secretはstepごとに要る物だけを渡し、AIを起こすstepにはLinearのキーを渡さない。main以外のrefの回はLinearに書かない。本番のdeployの門の条件には触れていない。

移した直後に一度つまずいた。試遊のdryの回が「ログインできていない」で落ちたのである。LinuxのWebKitは、Secureの付いたcookieをhttpのlocalhostに送らない。試遊用のcookieをsecure: falseにして直した。もう一つの遠回りは待ち方で、処理役はdryの回を裏で待つ間、進捗の印を57分更新せず、停滞の見回りに当たった。処理役が試遊を手で回す時の手順 (gh workflow runでdryの回を起こし、gh run watchで待ち、gh run downloadで結果を落とす) も規約に足した。

次は自動で止まる仕組みか

手元のlaunchdから外したので、この四つがA2の手元で走ることは無くなった。一方で、自動では止まらない物が二つ残る。

一つ目は、処理役が手で流すe2eである。端末Bでkernel_taskを膨らませたのはこちらだった。孤児のWebKitを落とす係と、門で手元のPlaywrightを数える係は別の課題に移しており、この記録には結果が無い。kernel_taskそのものには見張りを足した。見張りは、kernel_taskが4GB以上で画面が消えている時に、画面を1秒点ける。A2で画面を消してE2Eを流し、28GBまで膨らませてから、次の回で自動で戻ることを確かめた。

二つ目はCIの分数である。手元の負荷を外した分、Actionsの分数が増える。増え方は人が見積もって範囲を選ぶ形で、自動で止まる仕組みではない。CI側で重複を消す手は、効く余地が小さかった。E2EをPRの必須から外す前に直近の3,250 runを測ると、同じrefの重複は全分数の1.2% で、主要なCIには重複を消す設定 (concurrency) が既にあったので、設定は足していない。待ちの本体は1回のrunの長さだった。kanjiは、無人で本番に出す判定がPRのE2Eの結果を使うので、PRのE2Eを残した。

移した後の最初の夜に、深夜のkernel_taskの通知が出ないことを確かめる作業は、別の課題に移した。結果はこの記録にはまだ無く、効果は未測定である。

手元の定期実行を棚卸しする

手元のMacでAIのセッションを並べているなら、次の順で確かめておくと同じ詰まりを避けやすい。

  • launchdとcronを全部読み、ブラウザやE2Eを走らせる定期実行を、名前・時刻・所要・最大のメモリの表にする。
  • 表の一つずつをPRのCIと突き合わせ、同じ検査を回している物は手元から外す。
  • 移す前に、今月のCIの分数と、移すと増える分数を見積もり、移す範囲を決める。
  • 移したworkflowは、最初に手動の起動 (workflow_dispatch) でdryの回を流し、gh workflow runから結果を落とすまでを一度通す。
  • LinuxでWebKitを回すなら、Secureのcookieがhttpのlocalhostで送られるかを先に確かめる。
  • テストの所要時間だけでなく、終わった後のメモリ (kernel_task) も見張る。画面が消えている時間帯は特に見る。

筆者の見方

次は、移した後の夜にkernel_taskの通知が出ないことと、Actionsの月の分数を同じ表で並べて見る。手元の負荷を外すとCIの分数が増えるので、片方だけを見て良し悪しを決めない。この仕組みを自社で2週間で作りたい時は、スプリント0で相談を受けている。

この記事の作り方:社内の開発の記録 (issueと決定の記録) を材料に、処理役が下書きし、別のAIがレビューした。

数字は全て記録から写し、記録の無い数字は書いていない。

出典

に確認(日本時間)

  1. workflow_dispatch(docs.github.com)
  2. gh workflow run(cli.github.com)
  3. WebKit(playwright.dev)
  4. スプリント0(sagus.io)

この記事をシェア

この記事は役に立ちましたか