push 通知を取りこぼした側が、古い状態のまま戻らない。push に定期取得を足し、バージョンで束ねて、遅れても必ず追いつき、古い通知では状態を戻さないようにする。TypeScript で実装します。
在庫を読んでから書き戻すまでの隙に別の更新が入り、一方の更新が黙って上書きされる(Lost Update)。値にバージョンを持たせ、衝突した側だけ読み直してやり直させる。TypeScript で実装します。
フラグを1つ足すたびに、「待機中かつ実行中」のようなありえない組み合わせが倍に増える。状態を判別可能ユニオンにまとめ、遷移を型で縛る。TypeScript で実装し、足し忘れも型で止めます。
1分あたりの上限を決めても、固定窓の境目をまたぐと上限の2倍が通り抜ける。窓の区切りをやめ、トークンが一定の速さで溜まる Token Bucket に替えて流量を抑える。TypeScript で実装します。
JavaScript はシングルスレッドでも、ロックを取り合う2つの処理が互いを待って永久に止まる。ロックを取る順を全体で揃えて循環を断ち、タイムアウトの限界にも触れる。TypeScript で実装します。
非同期処理を一斉に走らせると、相手の接続を取り合って共倒れになる。同時に通す数を N に絞り、溢れた分は行列で待たせる(Semaphore)。TypeScript で実装し、同時実行数の最大値をテストで確かめます。
相手が落ちるたびに即リトライすると、回復する前にリクエストを使い果たし、再開時に殺到する。待ちを倍に伸ばす指数バックオフと、ばらつきを足す Full Jitter で避ける。TypeScript で実装します。
キャンセルした非同期処理が裏で動き続け、接続やカーソルを握りっぱなしになる。AbortSignal を処理の前・中・待機中の3か所で見るようにして止める。TypeScript で実装します。
非同期処理の途中(await の間)に同じ操作がもう一度入り、二重送信になる。実行中フラグを置く位置を直し、二度目の呼び出しを締め出す。TypeScript で実装し、テストで確かめます。
非同期処理や並行処理で起きる「たまにだけ壊れる」バグを、TypeScript のコードで直していく全12話の目次。困りごと別の一覧から、読みたい話を選べます。
在庫・課金・通知・配送は分けたのに、繋ぎ方だけが直結のN対Nで、通知を出す係が配線に散っていた。連絡を仲介役に集約して、部品同士が互いを知らなくて済むようにする(Mediator)。Go で実装します。
ログ・認証・recover・計測といった同じ前置きが30個のハンドラーにコピペされていた。先頭で呼ぶ関数では後処理が括れない理由を押さえ、ハンドラーを包む層に横断処理を集める(Middleware)。Go で実装します。
共通関数に抽出しても、引数に http.ResponseWriter を握っている限り HTTP の外からは呼べない。処理を Execute(ctx) error だけで話す部品に切り出し、ハンドラーからもワーカーからも同じ形で実行する(Command)。Go で実装します。
夜間バッチ3本が骨格ごとコピペで、共通のエラー処理の改修が1本だけ漏れ、接続断の朝にそのバッチだけ黙って正常終了した。骨格を1本に固定して工程だけ差し込む(Template Method)。Go で実装します。
圧縮・暗号化・バッファを組み合わせごとの型で抱え、最も複雑な型の閉じ処理を落としたせいで、復元した証跡の末尾が欠けた。同じ io.Writer を1枚ずつ被せて、掛け算で増える型を積み重ねに変える(Decorator)。Go で実装します。