Atomicは書きます —tempfile + os.replaceが破損したJSONを防ぐ方法
Atomic writes — how tempfile + os.replace prevent corrupted JSON
プロセスがコンフィグファイルに書き込み中に電源が切れた場合はどうなりますか? またはWindowsのアンチウイルスソフトウェアが簡単にファイルミッドライトをロックする場合? ファイルをnively上書きすると、割り込みの瞬間に部分的なコンテンツが何であるかは、ディスク上に残っているものです。 JSON では、通常は壊れた構文を意味し、次の起動時にスローし、設定全体が効果的に失われます。 この記事は、その防止のための標準的なテクニックを歩きます: 最初の一時ファイルへの書き込み、原子的にそれを交換します。 Note: "Atomic" は、ここでの操作は、完全に完了するか、まったく起こらないかを意味しています。 部分的なものはありません。 データベースのトランザクションに使われる単語と同じ意味です。 なぜ直接上書きは危険な効果的にトランクされています...
プロセスがコンフィグファイルに書き込み中に電源が切れた場合はどうなりますか? またはWindowsのアンチウイルスソフトウェアが簡単にファイルミッドライトをロックする場合? ファイルをnively上書きすると、割り込みの瞬間に部分的なコンテンツが何であるかは、ディスク上に残っているものです。 JSON では、通常は壊れた構文を意味し、次の起動時にスローし、設定全体が効果的に失われます。 この記事は、その防止のための標準的なテクニックを歩きます: 最初の一時ファイルへの書き込み、原子的にそれを交換します。 Note: "Atomic" は、ここでの操作は、完全に完了するか、まったく起こらないかを意味しています。 部分的なものはありません。 データベース取引に使われる単語の同じ意味です。 直接上書きが危険である理由は、最初にファイルをトランクし、新しいコンテンツを書き込みます。 そのウィンドウの間にプロセスが中断されている場合は、ファイルが空のまままたは不完全なコンテンツを保持します。 原因は異なります: , 電源不足, ウイルス対策ソフトウェア 簡単にWindows上でファイルアクセスをブロックします。, または バックアップツールは、ファイル中書き込みをつかむ. ローカル開発中には稀に再現されるが、長期生産環境では、最終的には確実性で起こります。 修正: テンプファイルに書き、コアのアイデアで交換するのは簡単です。 ターゲットファイルを直接触れないでください。 完全な新しいコンテンツを一時ファイルに最初に書き込み、完全に成功した書き込みを確認し、そのテンプファイルでターゲットファイルを置き換えます。 衝突のない一時的なファイル名を生成し、そのファイルの記述子を返します。 ここでの引数は、対象ファイルと同じディレクトリにテンプファイルを置くことで、次の呼び出しは単一のファイルシステム内で保持されます。 なぜアトミックなのか このパターンのコアは最終呼び出しです。 Python の公式ドキュメントは、「Unix 上で原子動作する」と、両方のパスが同じファイルシステムにある限り、Windows 上で原子的に動作します。 POSIX システム(Linux/macOS)では、このマップをシステムコールにマップします。 カーネルレベルでは、ディレクトリのエントリを交換することは、単一の不可分な操作です。 外部から観察する中間状態はなく、そのプレスワップまたはポストスワップ状態にあるファイルです。 Windows では、Python 3.3+ は、既存のファイルを上書きするように実装します。(フラグと呼ぶのに相当します)。 このプロパティのおかげで、プロセスが途中で死ぬ場合、名前の付いていないテンプルファイルだけが影響されます。実際のコンフィグファイルは以前の有効な状態に触れられません。 アトミックであっても、ディスクに永続性を強制する、サブトラーリスクがあります。電源が失われるとき、ディスクの物理的にではなく、OSページキャッシュに書かれているコンテンツは、まだ座っている可能性があります。 その場合の名前自体が完成する可能性がありますが、名前変更されたファイルの内容は実際に書かれていたものを反映していない可能性があります。 お問い合わせ Python の内部バッファを OS にプッシュするだけで、OS レベルのキャッシュに残っている可能性があります。 手順をさらに進めて、データが実際に物理的なディスクに書かれているまで待つOSを尋ねます。 両方のステップを組み合わせると、テンプファイルのコンテンツがディスク上で時間が実行されるようにします。 失敗した書き込み後のクリーンアップ テンプファイルへの書き込み自体が、(ディスクフル、パーミッションエラーなど)を経由して途中で失敗した場合、ターゲットファイルが影響を受けません。 しかし、ディスクの背後にある半書き込みテンプファイルが残っています。 これらは乱雑に蓄積されるので、故障時に明示的に削除する価値があります。 自身が失敗する可能性のあるネストされたアカウント(すでに削除、許可なしなど)。 元の例外()を再取得すると、呼び出し主は、書き込みが失敗したことをまだ学習します。 残りファイルを監視する テンプファイル名を消費し、成功のターゲット名に交換するので、通常は通常の動作下ではリンガーは使用しません。 しかし、極端なエッジケースでは、プロセスは、テンプファイルが完全に書かれている直後に狭いウィンドウで 'd を取得しますが、