Featured image of post コードテイマー【Graceful Shutdown】終いを急ぐ獣が、還らぬ客と開いた鍵を闇に残す〜受け入れを閉ざし、皆を還してから己を閉じる〜

コードテイマー【Graceful Shutdown】終いを急ぐ獣が、還らぬ客と開いた鍵を闇に残す〜受け入れを閉ざし、皆を還してから己を閉じる〜

湯守の信条は、訪れた客を一人残らず気持ちよく帰すことだった。夜明け前、街に早鐘が鳴って急な仕舞いを命じられたその折に、湯に浸かったままの客が、還らなくなった——出てもいない、中にもいない。だが仕舞いの術に欠陥は一つも無い。客のいない空の湯屋でいくら試しても、何も起きない。原因は術の中にはない。「客がまだ居る」のに「もう閉じる」を同じ一息にやらせた設計が、上がり際の客から上がり湯を奪い、火を還さず栓を開けたまま、その場を捨てさせた。空では暴れぬ獣を、客が湯に浸かっている最中の早鐘で初めて檻に再現し、上がり湯を断たれた客が倒れること、何も還さず抜ければ火は燻り栓は開き客は宙吊りのまま虚無へ落ちることを、決定的な模擬戦で確かめる。直し方は、たった一手——火と水を還す前に「客が皆、自分の足で上がるのを待つ」を挟むこと。二度目の早鐘は聞き流し、新規を断ち、皆の上がりを刻限つきで待ち、それから順に鍵を返す。行儀の悪い終端が残す還らぬもの——解放漏れの資源、死なぬ接続、宙吊りの約束——を、カイナは初めてその名で呼ぶ。NULL。皆を還してから己を閉じる、その小さな終い方の TypeScript の契約の物語。

Featured image of post コードテイマー【Bulkhead】汲み上げの大食らいが船中の魔力を飲み干し、守りの防壁が飢えて落ちる〜魔力槽を機能ごとに隔て、守りの取り分を絶やさない〜

コードテイマー【Bulkhead】汲み上げの大食らいが船中の魔力を飲み干し、守りの防壁が飢えて落ちる〜魔力槽を機能ごとに隔て、守りの取り分を絶やさない〜

機関長の信条は、船のどの機能も絶やさぬことだった。嵐の夜、浸水で汲み上げの詠唱が忙しくなったその折に、船を守る防壁が落ちた——だが防壁の術式に欠陥は一つも無い。一度も失敗していない。健全なのに、発動すらしなかった。原因は防壁の中にはない。どの詠唱も同じ一つの炉から魔力の取り出し口を引く設計が、汲み上げの暴食に取り出し口を喰い尽くされ、防壁の番を永遠に来させなかった。失敗していないものを、断つ結界(Circuit Breaker)では救えない。これは断つ獣ではなく、分ける獣だ。汲み上げを絞っても、空いた隙間は別の大食らいが喰う——取り分は絞って空けるのでなく、初めから機能ごとに分けて取って置く。魔力炉を機能ごとの区画(Bulkhead)へ隔て、防壁の取り出し口を汲み上げの槽とは別オブジェクトのカウンタにすることで、大食らいが構造的に触れられなくする。汲み上げを Deferred で炉に居座らせ、区画ごとの取り出し口を数で観る決定的な模擬戦で、共有炉では防壁が飢え、区画化では同じ殺到でも防壁が無傷であることを確かめ、見せかけの隔離・融通の喪失・槽の見積もりまで線引きする TypeScript の契約の物語。

Featured image of post コードテイマー【Circuit Breaker】倒れた一匹を見捨てられず、群れごと魔力が枯れ果てる〜倒れた相手への鎖を断ち、頃合いを見て繋ぎ直す〜

コードテイマー【Circuit Breaker】倒れた一匹を見捨てられず、群れごと魔力が枯れ果てる〜倒れた相手への鎖を断ち、頃合いを見て繋ぎ直す〜

中央郵便局の差配は、辺境の便も絶やさぬことを矜持にしてきた。末端の一配送所が魔力災害で倒れた夜、その一つを諦めきれず使い魔を送り続けた——だが倒れた相手を待つほど、待つこと自体が使い魔を食い潰す。応答を失った中央局は黙り込み、その沈黙が呼び出しの鎖を登って、倒れた配送所とは無縁の健全な地方の便まで凍りつかせた。差配は「倒れた配送所を補強すれば(早馬=リトライを増やせば)防げる」と信じて来るが、それは倒れた相手に群がる狼を増やし共倒れを早めるだけだ。直せないのは倒れた相手で、守るべきは待つ側。失敗が続けば鎖を断ち(Open)即座に軽い間に合わせ(Fallback)を返して使い魔を空け、頃合いを見て一筋だけ試しに送り(Half-Open の単一プローブ)、通れば繋ぎ直す(Closed)。倒れた配送所を Deferred で握り論理時計で刻を進める決定的な模擬戦で、連鎖がどこで断たれるかと、回復中の群がりを一筋に絞る理由まで確かめる TypeScript の契約の物語。

Featured image of post コードテイマー【Eventual Consistency】取りこぼした叫びのあと、その階層だけが古いまま黙り込む〜叫びと巡回の二本を版で束ね、遅れても必ず追いつかせる〜

コードテイマー【Eventual Consistency】取りこぼした叫びのあと、その階層だけが古いまま黙り込む〜叫びと巡回の二本を版で束ね、遅れても必ず追いつかせる〜

ギルドの中継係は、速さを誇りにしてきた。主が落ちた瞬間、迷宮の全階層の討伐状況板へ叫びを飛ばし、寸分の狂いもなく揃える。だが全階層の即時の復唱を強いるほど、こだまは反響を増幅し、魔力回線を灼いて自ら黙る。灼けた隙に叫びを取りこぼした階層は、討伐済の主を未討伐のまま掲げ続け、永久に追いつけない。叫び(push)は速いが取りこぼす。では巡回(poll)だけにすれば、今度は自分が仕留めた報せすら次の巡回まで自分の板に出ない(read-your-writes の崩れ)。速さを捨てず、即時の強制だけを捨てる。叫びは残し、取りこぼしの保険に定期巡回を足し、二本の報せを版で冪等に束ねる。ズレを禁じるのではなく、ズレに刻限を与える。取りこぼしを次の巡回で必ず拾い、古い叫びの後着では倒した主を蘇らせない結果整合性を、決定的な模擬戦で確かめる TypeScript の契約の物語。

Featured image of post コードテイマー【Optimistic Locking】二人の手が同じ数を書き、一方の更新が静かに消える〜帳に版を刻み、後から来た手にやり直させる〜

コードテイマー【Optimistic Locking】二人の手が同じ数を書き、一方の更新が静かに消える〜帳に版を刻み、後から来た手にやり直させる〜

隊商の差配役は、四十年、帳面で食ってきた。注文を二つ受け、どちらも正しく記した。書き損じはない。なのに棚卸しで数が合わない——台帳には二つの引き当てが立つのに、蔵の残りは片方しか減っていない。片方の取引が、最初から無かったかのように消える。残りを問う早馬が戻る間に、別の窓口が同じ古い残りを持ち帰り、後から書いた手が先の手を音もなく塗り潰す(Lost Update)。JS が一度に一つしか書かなくても、読んでから書くまでの隙に二人が同じ古い数を握れば、一方の更新は消える。残りの数でなく版を壺に刻み、書き戻す時に読んだ版と今の版を照らして、ぶつかった手だけを読み直させてやり直させる(Optimistic Locking)。消失を決定的に注入した模擬戦で、版が単調に増えるからこそ ABA の往復も見逃さないことまで確かめる TypeScript の契約の物語。

Featured image of post コードテイマー【State Machine】氷の貌のまま、獣は炎を吐いて自壊する〜札を足さず、貌をただ一つに畳む〜

コードテイマー【State Machine】氷の貌のまま、獣は炎を吐いて自壊する〜札を足さず、貌をただ一つに畳む〜

王宮の防衛術式が、味方を撃った。引き継いだ術師は、矛盾が露れるたびに札(boolean フラグ)を一枚ずつ足して塞いできた——どの一枚も、その時は正しかった。だが「待機中」の札と「発動中」の札は別々に立ち、ある中断の手順が両方を灯したまま残す。待機の貌をしたまま、術式は前を横切った味方へ放たれる。札を増やすほど、ありえぬ貌は倍々に増える(n枚で2のn乗通り)。札で数えるのをやめ、貌をただ一つの型に畳めば(Discriminated Union+状態遷移)、「待機中かつ発動中」はそもそも書けなくなる。実行時のifで弾くのでなく、コンパイル時に存在を消す。新しい貌を足したとき道の描き漏らしを型が止める(never網羅検査)TypeScriptの契約の物語。

Featured image of post コードテイマー【Token Bucket】窓が改まる刹那、汲み手は源を二度干す〜窓で区切らず、雫の溜まる速さで流量を律する〜

コードテイマー【Token Bucket】窓が改まる刹那、汲み手は源を二度干す〜窓で区切らず、雫の溜まる速さで流量を律する〜

配水技師は源が涸れるたび善意で「一刻あたりの汲み上限」を設けた。どの刻も帳簿はきっちり上限で止まる。一度も超えていない。なのに街は渇く——決まって、刻の変わり目に。固定窓は窓ごとにカウンタを0へ戻す。その「0に戻す」一瞬が前の刻をまるごと忘れさせ、継ぎ目をまたいだ手は忘れられた帳簿で二度、上限まで汲む。上限の2倍が源を干す。窓で刻むのをやめ経過ぶん雫を連続で溜める器(Token Bucket)に差し替えれば、継ぎ目そのものが消える。境界バーストを注入時計の模擬戦で決定的に再現し、同時数(門番)とは別の物差し=時間あたり流量を律するTypeScriptの契約の物語。

Featured image of post コードテイマー【Deadlock】二つの釜が、互いの鍵を見つめ合って石になる〜鍵を拾う順を一つに定め、にらみ合いを解く〜

コードテイマー【Deadlock】二つの釜が、互いの鍵を見つめ合って石になる〜鍵を拾う順を一つに定め、にらみ合いを解く〜

二つの自動錬金釜は、単体ではどちらも完璧だった。なのに同時に動かすと、片方が水の鍵を握って火の鍵を待ち、もう片方が火の鍵を握って水の鍵を待ち——互いの一手を見つめ合ったまま石になる。データは壊れない。ただ、永久に止まる。JSはシングルスレッドでもデッドロックは無縁ではない。鍵を拾う順を全アプリで一つに揃え、循環の待ち合いを構造から断つLock Orderingと、復旧策のTimeoutの代償を、永久ハングを決定的に可視化した模擬戦で確かめるTypeScriptの契約の物語。

Featured image of post コードテイマー【Semaphore】一斉になだれ込む群れが、宝の通路を圧し潰す〜門番が通すのはN体、溢れは行列で待たせる〜

コードテイマー【Semaphore】一斉になだれ込む群れが、宝の通路を圧し潰す〜門番が通すのはN体、溢れは行列で待たせる〜

採れ高を上げようと、監督官は使い魔を一斉に坑道へ放った。群れは宝の通路を同時に塞ぎ、坑道ごと圧し潰す。鍵は総数でも投入の間隔でもなく、同時に通路を占める数だった。入口に門番を立て、同時に通すのをN体に絞り、溢れた群れは行列で待たせる——同時占有ピークを物差しにした模擬戦で、有界並行こそ最速の持続採掘だと確かめるTypeScriptの契約の物語。

Featured image of post コードテイマー【Exponential Backoff】焦りの雷鳥は、嵐の前に羽を使い果たす〜待つ刻を倍にし、揺らぎで群れを散らす〜

コードテイマー【Exponential Backoff】焦りの雷鳥は、嵐の前に羽を使い果たす〜待つ刻を倍にし、揺らぎで群れを散らす〜

魔力嵐で本塔が黙るたび、通信士は雷鳥を連発した。だが連発するほど届かない——焦りの雷鳥は、嵐が去る前に羽を使い果たす。失敗ごとに待ちを倍へ伸ばす指数バックオフと、群れを散らすFull Jitterの契約を、sleepを論理時計に変えた模擬戦で検証する物語。

Featured image of post コードテイマー【AbortController】消えた検索が、書庫の奥で魔力を啜る〜AbortSignalを鎖に、残影の霧を断つ〜

コードテイマー【AbortController】消えた検索が、書庫の奥で魔力を啜る〜AbortSignalを鎖に、残影の霧を断つ〜

夕暮れになると図書館の魔力が漏れる。打ち直して閉じたはずの検索が、裏で書庫を潜り、鍵を握り続けていた。AbortSignalを潜行前・潜行後・待機中の三つの刻にhonorさせ、残影を霧散させるTypeScriptの契約を、同時保持カーソル数の模擬戦で検証する物語。

Featured image of post コードメカニック【Mediator】部品は全部直したのに、最後に全部が絡んでいた〜直結をやめ、仲介役にすべてを捌かせる〜

コードメカニック【Mediator】部品は全部直したのに、最後に全部が絡んでいた〜直結をやめ、仲介役にすべてを捌かせる〜

キャンセル機能を足したら、同じ確認メールが客に二通届いた。在庫・課金・通知・配送は綺麗に分けたのに、繋ぎ方だけが直結のN対Nで、通知を出す係が配線に散っていた。部品同士の直結をやめ、仲介役に連絡を集約するMediatorの整備記録。

Featured image of post コードメカニック【Middleware】一行変えるのに、三十回ボンネットを開けた〜各車に貼った同じ点検を、通り抜ける一本のラインへ〜

コードメカニック【Middleware】一行変えるのに、三十回ボンネットを開けた〜各車に貼った同じ点検を、通り抜ける一本のラインへ〜

ログ・認証・recover・処理時間の計測といった同じ前置きが、30個のハンドラーにコピペされていた。リクエストIDの形式を一行変えるだけで30ファイルを直す羽目になる。先頭で呼ぶ共通関数では後処理とrecoverが括れない理由を解き、ハンドラーを包む func(http.Handler) http.Handler の層に横断処理を集約するMiddlewareの整備記録。

Featured image of post コードメカニック【Command】一日見積もりが、底なしだった〜ハンドラーに作り付けた仕事を、一個の命令に切り出す〜

コードメカニック【Command】一日見積もりが、底なしだった〜ハンドラーに作り付けた仕事を、一個の命令に切り出す〜

共通関数に抽出しても、引数に http.ResponseWriter を握っている限りHTTPの外からは呼べない。物件登録のロジックを Execute(ctx) error だけで話すCommandに切り出し、HTTPハンドラーからもフィード取り込みワーカーからも、同じ部品を組み立てて実行できるようにした整備記録。