公開日
デプロイで記事が全部消える事故を、安全装置で止める
記事をデプロイのたびに DB へ反映する仕組みでは、content が空のまま反映されると全記事が非公開になる。半分以上を非公開にするなら止める安全装置を入れたら、記事が 1 本のときに誤作動した。なくす案と比べて残し、記事が少ない間の閾値を変えた話。
何が怖いか
前回書いたとおり、記事はリポジトリの content/ を正本にして、デプロイのたびにマイグレーション用の Lambda が DB へ反映する。content に無い公開中の記事は非公開にする。
この仕組みで一番怖いのは、content が空のまま反映されることだ。S3 のキーの指定を間違えた、zip の展開に失敗した、ディレクトリの構成を変えた。どれも「記事が 0 件」という同じ形になる。しかも 0 件の反映は正常に終わる。デプロイは成功、サイトからは記事が全部消える。
非公開にするだけで DELETE はしないので、DB の行は残る。content を直して再デプロイすれば戻る。取り返しのつかない事故ではない。それでも、気づかないままデプロイが成功するのは流石に嫌なんだよな。
安全装置
反映の前に、公開中の記事のうち何本を非公開にすることになるかを数える。公開中の半分以上を非公開にするなら、何も書かずに止める。content が 0 件なら当然止まる。意図して大量に下げるときだけ、環境変数で安全装置を外す。CDK の context で渡す形にして、既定では渡さない。
DB にも content にも公開中の記事が無いときは止めない。最初の記事が入るまでのデプロイを通すためだ。
判定は、DB に書く前に 1 回だけ行う。止まったときは DB に何も書いていない。
記事 1 本で誤作動した
最初の記事を公開した後、テストのために draft: true に戻してデプロイしたら、止まった。公開中 1 本のうち 1 本を非公開にするので、半分以上に当たる。
誤作動ではあるが、ルールどおりといえばルールどおり。記事が少ない間は、1 本下げただけで「半分以上」になる。記事が 2 本でも同じだ。そこから「そもそもこの安全装置は要るのか」を AI(Claude Code)と壁打ちしながら比べた。
残すか、なくすか
| 残す | なくす | |
|---|---|---|
| 守れる事故 | content の読み込み先が空で全記事が非公開になるのを、デプロイ前に止める | 守らない。非公開になっても DB の行は残るので、戻せば復旧する |
| 復旧の手間 | 事故なし | content を直して再デプロイ。その間サイトは記事 0 件。いいねとアクセス数は残る |
| 運用の手間 | 意図して大量に下げるときだけ環境変数で外す | なし |
| 誤作動 | 記事が少ない間に起きる。閾値の緩和でほぼ消える | なし |
なくす案の言い分はシンプル。取り返しがつくなら、検出器は不要。運用の手間も誤作動もなくなる。
残すことにした。決め手は、守りたい事故が「設定ミスで一番起きやすい形」であり、検出が安いことだ。数を数えて比べるだけで、DB への書き込みもない。復旧できるとしても、気づくのが翌日になれば、その間サイトは記事 0 件だ。個人のサイトなので実害は小さいが、気づく仕組みが無いことの方が気持ち悪い。
記事が少ない間は閾値を変える
誤作動の方は、閾値で消した。公開中が 3 本未満のときは「全部を 0 本にするとき」だけ止める。3 本以上は「半分以上」のまま。
static boolean unpublishesTooMany(long published, int toUnpublish) {
if (published == 0) {
return false;
}
if (published < FEW_POSTS) { // 3
return toUnpublish >= published;
}
return toUnpublish * 2L >= published;
}
テストには、2 本中 1 本を下げても止まらないこと、閾値の前後の判定を足した。記事 1 本を draft に戻すテストは、これで通る。
記事が増えれば「半分以上」が効き始める。3 本という数に深い根拠はない。1 本や 2 本で半分を数えても意味が無いだろ、という程度のもの。記事が増えたら見直すかもしれないが、後から変えにくいものではない。
学び
- 「0 件」は、設定ミスで一番起きやすい形だ。0 件の反映が正常に終わる仕組みには、0 件を疑う検出器が要る
- 検出器が安ければ、守る事故が小さくても残してよい。なくす案との比較表を書くと、どちらを選んでも理由を説明できる
- 閾値は、データが少ない間だけ別のルールにする。少ないときに割合で判定すると誤作動する
比較表の観点は AI と一緒に出したが、残すかどうかと閾値の数は自分で決めた。「記事が少ない間は環境変数で安全装置を外して運用する」という逃げ道もあった(記事が少ないのでセーフ)。ただ、外す操作が日常になると、本当に必要なときに付け忘れる。閾値を変える方が、運用に人の手が入らない。こういうところはやっぱ AI に決めさせず、自分で選ぶ。
次回は、AI に画像で案を出させてポートフォリオのデザインを決めた話を書く予定。