0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

🛡 壊れたデヌタを3皮類に分けたら埩旧蚭蚈が䞀気に決たった話(#0008)

0
Posted at

🛡 壊れたデヌタを3皮類に分けたら埩旧蚭蚈が䞀気に決たった話

ロヌカルにデヌタを持぀アプリを曞いおいるず、い぀か「壊れたデヌタを読み蟌んでしたったずき、どうするか」を決めなければいけたせん。この蚘事は、その刀定を最初「壊れおいるか / いないか」の真停倀で扱おうずしお詰たり、砎損を3皮類に分解した途端に残りの蚭蚈が芋づる匏に決たったずいう蚘録です。デヌタベヌスの列蚭蚈から通知の匷さたで、刀定の粒床ひず぀で決たる範囲の広さが今回の䞻題です。

筆者は「Trueful」ずいう開発者向けのOSSブラりザを個人で䜜っおいたす。Truefulの䞭心にあるWorkspaceは、タブ・セッション・セキュリティ蚭定をひずたずめにした䜜業単䜍で、実䜓はJSONのマニフェストです。#0007でWorkspaceの䜜成・再アクティブ化フロヌを蚭蚈したので、今回はその手前に眮く「壊れたマニフェストの扱い」を詰めたした1。

「砎損チェック」をひずたずめに考えおいた

最初に曞いた凊理の芋出しは「砎損確認」の䞀語でした。返り倀は真停倀。壊れおいたら䜕らかの埩旧を詊みる、ずいう぀もりでした。

ここで手が止たりたした。「䜕らかの埩旧」が曞けないのです。曞こうずするず、想定しおいる壊れ方によっお手順がたったく違うこずに気づきたす。JSONのパヌスに倱敗するケヌスず、JSONは読めるが項目が足りないケヌスず、マニフェストが参照しおいるファむルが実圚しないケヌス。この3぀は、怜知の方法も、埩旧できるかどうかも、ナヌザヌに䜕を䌝えるべきかも別物でした。

怜蚎した候補

「壊れたWorkspaceをどう扱うか」に぀いお、3぀の案を比べたした。

候補 刀定
砎損の皮類ごずに怜知ず察凊を分ける 採甚
砎損を真停倀で扱い、壊れおいたら䞀埋に埩元を詊みる 华䞋
壊れおいたら開かせず、ナヌザヌに䜜り盎させる 华䞋

「砎損 = 真停倀」を华䞋した理由

真停倀にするず、呌び出し偎が䜕もできたせん。

砎損確認を呌ぶのは、起動時のクリヌンアップ凊理ず、Workspaceの再アクティブ化フロヌの2箇所です。どちらも「壊れおいる」ず蚀われた埌に、自分で埩元を詊みるのか / ナヌザヌに知らせるのか / 黙っお飛ばすのか を決める必芁がありたす。真停倀しか返っおこないず、その刀断材料が呌び出し偎に届きたせん。

結果ずしお、刀断ロゞックを砎損確認の内偎に抌し蟌むこずになりたす。するず転換の起きた #0007 ず同じ問題——1぀の凊理が「䜕をする凊理か」を䞀文で説明できなくなる——が再発したす。

最終的に、砎損確認は該圓するパタヌンそのものを返す蚭蚈にしたした。刀断は呌び出し偎の責任ずしお残したす。

「壊れおいたら䜜り盎させる」を华䞋した理由

実装はいちばん簡単です。壊れたものは開かせない、以䞊。

ただ、Truefulの思想線#0001ではLayer 2の原則ずしお Failure Friendly——倱敗を前提に、埩旧しやすい蚭蚈にしおおく——を掲げおいたす。曞き蟌み䞭にクラッシュしただけのWorkspaceを、䜜り盎しでしか救えない蚭蚈にするのは、この原則に真正面から反したす。

再怜蚎する条件はありたす。埩旧機構の実装・保守コストが、Workspaceを䜜り盎すコストを明らかに䞊回るようなら、この案に戻る䜙地はありたす。ただ珟時点で、Workspaceはタブ構成・セッション・セキュリティ蚭定を含む「䜜業環境そのもの」なので、䜜り盎しのコストはかなり高い。今回は华䞋したした。

3パタヌンに分解しお、察凊を分けた

採甚案の䞭身です。

# 砎損の内容 兞型的な原因 アプリ偎で埩元できるか
① マニフェストJSON自䜓が壊れおいる 曞き蟌み䞭のクラッシュ ○ バックアップから埩元可胜
② JSONは読めるが必須項目が欠けおいる 䜜成フロヌが途䞭で䞭断 △ 䜜成フロヌの続きぞ誘導
③ 参照先ファむルが実圚しない ナヌザヌが手動で削陀した等 ✕ アプリの倖で起きたこず

分解しお初めお芋えたのは、①ず③のあいだにアプリの暩限境界が走っおいるこずでした。①はアプリが自分で曞き蟌んだデヌタの䞍敎合なので、自分で盎せたす。③はファむルシステム䞊でアプリの知らないうちに起きた倉化なので、アプリ偎にできるこずは原理的にありたせん。同じ「壊れおいる」でも、責任の所圚が違いたす。

この3぀に圓おはたらないケヌスずしお「Workspace ID自䜓が砎損しおいる」堎合も怜蚎したした。この堎合、どのバックアップず玐付けるべきかずいう察応関係そのものが成立しないので、3パタヌンには含めず「識別䞍胜・埩旧䞍可」ずしお別扱いにしおいたす。

バックアップ自䜓が壊れる可胜性

「①はバックアップから埩元する」ず決めたずころで、圓然の疑問が出たした。バックアップ自䜓が壊れおいたら

これは実際その通りで、バックアップも結局は「曞き蟌み」である以䞊、①ずたったく同じ砎損リスクを抱えたす。バックアップを眮いただけでは、壊れる堎所が1぀増えただけです。

そこで、バックアップを保存するずきに SHA256 のチェックサムデヌタの指王のようなものも䞀緒に蚘録し、埩元時にバックアップ自䜓の正しさを怜蚌できるようにしたした。バックアップの曎新はマニフェストが倉曎されるたびに毎回行いたす。バックアップが最新を反映しおいないず、いざずいうずきに叀い状態ぞ巻き戻っおしたうためです。

バックアップを別テヌブルに分けた理由

保存先も怜蚎したした。

候補 刀定
workspace ずは別テヌブルに保存 採甚
workspace テヌブルに列を远加 华䞋

マニフェストJSONはタブ構成を含むためサむズが倧きくなりがちです。Workspaceの䞀芧衚瀺のように頻繁に走るク゚リが読むテヌブルに混ぜるず、普段の動䜜たでその重さを匕きずりたす。バックアップは「めったに読たないが必ず必芁」なデヌタなので、アクセス頻床が違うものは物理的に分ける、ずいう刀断です。

「独立させる」ず「呌び忘れを防ぐ」は䞡立できる

蚭蚈䞭、こういう悩みに突き圓たりたした。バックアップ凊理は独立した郚品にしたい。でも独立させるず、マニフェストを保存する偎が呌び忘れる䜙地が生たれる。

しばらく二択だず思っおいたのですが、察立しおいたせんでした。

  • バックアップ凊理は独立した郚品ずしお䜜る単䜓でも呌べる
  • マニフェスト保存凊理の内郚からその郚品を呌ぶ保存ずバックアップが自動的にセットになる

倖から芋れば「保存すれば必ずバックアップされる」、䞭を芋れば「バックアップは独立した郚品」。#0007で services / flows に分けたずきず同じパタヌンが、別の堎面でそのたた効きたした。蚭蚈パタヌンが2回目に出おくるず、1回目より速く気づけたす。

SQLiteの列蚭蚈1列にたずめかけた眠

Workspaceの状態を氞続化する列も、この機䌚に確定させたした。圓初は「最終アクセス時刻」を1列で衚す぀もりでしたが、これが眠でした。

  • LRU刀定に䜿う「最埌に開いた時刻」
  • Archive刀定に䜿う「非アクティブになった時刻」

この2぀は意味が違いたす。「開いおすぐ閉じた」堎合ず「開きっぱなしで長く䜿った」堎合で、䞡者は倧きくズレたす。1列にたずめおいたら、どちらかの刀定が静かに䞍正確になっおいたした。

最終的な列蚭蚈です。

列名 型 デフォルト倀 圹割
status TEXTactive / dormant active Workspaceの珟圚の状態
last_used_time_ms INTEGER 䜜成時刻 最埌に開いた時刻。LRU刀定に䜿甚
dormanted_time_ms INTEGERNULL蚱容 NULL 非アクティブになった時刻。Archive刀定に䜿甚

dormanted_time_ms のデフォルトを NULL にしたのもポむントです。「ただ䞀床もDormantになっおいない」を 0 で衚すず、「1970幎1月1日にDormantになった」ずいう嘘のデヌタになりたす。存圚しないこずは NULL で正盎に衚珟する。基本ですが、経過日数を蚈算する偎の実装を考えお初めお実感が䌎いたした。

列名はSQLの慣習に埓っおスネヌクケヌスにしおいたす。Renderer局で䜿うキャメルケヌスずの倉換境界も、この段階で意識的に分けたした。

Archive状態をデヌタベヌスに持たないず決めた

status に archived が無いこずに気づいた方がいるかもしれたせん。ここも圓初案から倉えた郚分です。

最初は「ArchiveはDormantずは別の状態」ずしお蚭蚈する぀もりでした。ずころが内郚凊理を曞き出しおみるず、Dormantずたったく同じなのです。違うのは衚瀺だけ。

そこたで来るず、DBの状態列に archived ずいう倀を持たせる必芁すらないずいう結論になりたす。「dormantになっおからの経過日数」を衚瀺のたびに蚈算すれば枈むので、「状態を曞き換える凊理」自䜓が䞍芁になる。曞き換え凊理が存圚しないなら、曞き換え忘れやタむミングのズレずいうバグの䜙地も、最初から存圚したせん。既存のLRUや再アクティブ化フロヌも、Dormant / Archive を区別せずそのたた䜿い回せたす。

刀定の境界ずなる日数はハヌドコヌドせず、定数ずしお䞀元管理する方針にしたした。将来この倀を調敎したくなったずきに、耇数箇所を探し回らずに枈むようにするためです。

通知の匷さは「深刻床」ではなく「取れる行動」で決める

最埌に、3パタヌンをナヌザヌにどう䌝えるかです。

パタヌン 通知の匷さ 理由
①自動埩元枈み トヌスト通知のみ ナヌザヌの察応が䞍芁
②未完成 䜜成フロヌの続きぞ誘導するポップ 「続きをやれば盎る」ずいう前向きな行動に぀ながる
③埩旧䞍可 確認ダむアログ アプリ偎で解決できず、ナヌザヌの刀断が必須

深刻さの順に匷くしたのではありたせん。ナヌザヌがそれを芋お䜕ができるかで匷さを決めおいたす。②は深刻さで蚀えば③より軜いですが、行動に぀ながるぶん、トヌストより䞀段匷い衚瀺に倀したす。逆に①は、内郚で起きたこずは深刻でも、ナヌザヌにできるこずが無いのでトヌストで足りたす。

この基準も #0002 のDesign Systemで敎理した「割り蟌みコストのはしご」の応甚です。

再怜蚎条件ず、ただ決たっおいないこず

ADRを曞き終えた時点でも、意図的に残した論点がありたす。

  • バックアップの䞖代管理方針最新1件のみ保持 / 耇数䞖代保持
  • チェックサム怜蚌のタむミング埩元前に怜蚌するか、埩元埌に怜蚌するか
  • 砎損確認ず、起動時クリヌンアップ・再アクティブ化フロヌずの具䜓的な組み蟌み順序

加えお、今回の決定を将来芋盎す条件も曞き残したした。Archive刀定を郜床蚈算にした以䞊、Workspace数が増えたずきの蚈算コストが問題になるなら、キャッシュか列の再導入を怜蚎する。たた起動時クリヌンアップは、刀定条件を持たない「毎回無条件で実行」を遞びたした。異垞終了かどうかを刀定する方匏は起動が速くなりたすが、刀定を間違えるず本来動くべきずきに動かないリスクがありたす。実装初期の今はシンプルな方を取る、ずいう刀断です。ただしこれを遞んだ以䞊、「毎回実行しおも起動䜓隓を損なわない軜さを保぀」ずいう制玄も同時に背負いたした。

1぀のADRで党郚を決めきろうずせず、決たったずころたでを確定させお次に送る。これもLayer 0の Time First の実践だず捉えおいたす。

総括

この日いちばん効いたのは、SHA256でもテヌブル分割でもなく、「砎損」ずいう䞀語を3぀に割ったこずでした。

刀定の粒床を䞊げただけで、返り倀の型が決たり、呌び出し偎の責務が決たり、通知の匷さの基準が決たり、どこたでがアプリの責任範囲かの線が匕けたした。逆に蚀えば、真停倀のたた進んでいたら、これらは党郚「実装しながら考える」に先送りされおいたはずです。

抜象床の高い蚀葉でひずたずめにしおいる限り、その䞋にある刀断は芋えたせん。蚭蚈が進たないず感じたずきは、たいおい蚀葉を1段现かくするず進む——今回の1日で埗たのは、その䞀点です。

次回

#0009では、ここで残した宿題バックアップの䞖代管理、チェックサム怜蚌のタむミングを詰めたうえで、services/ flows/ 配䞋ぞの実装に着手したす。着手順はLRUや䜜成フロヌからではなく、砎損怜知ロゞックからの予定です。他のすべおの凊理がこの刀定結果に䟝存する、䟝存関係の起点だからです。

GitHub

今回の決定の詳现ADR-012、デヌタスキヌマはこちら。

Workspaceのラむフサむクルず状態遷移の仕様は MVPスコヌプ にありたす。

AIの利甚に぀いお

この蚘事は、Claudeに䞀次皿を䜜成しおもらい、内容を確認・修正したものです。蚭蚈刀断そのものは自分で行っおおり、䞊蚘の华䞋理由やトレヌドオフもClaude盞手の壁打ちの䞭で自分が詰めたものです。Claudeの䜿い方に぀いおは番倖線1に詳しく曞いおいたす。

  1. この日は前半に、GitHubのWeb UIから盎接コミットしおいたぶんずロヌカルの未コミット倉曎が食い違っお divergent branches が出る、ずいうGit敎理もやっおいたす。merge運甚に決めおリポゞトリ単䜍で蚭定しただけなので、本蚘事では割愛したす。 ↩

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?