Обновить

Скрипт обновил JSON, а читатель получил половину файла

Рассмотрим домашний сервер: один скрипт собирает показания датчиков в status.json, другой читает этот файл для страницы состояния.

Обновление выглядит привычно:

with open("status.json", "w", encoding="utf-8") as f:
    json.dump(data, f)

Режим w обнуляет существующий файл при открытии. Между этим моментом и завершением записи читатель может получить пустой или частично записанный JSON. Если пишущий процесс завершится с ошибкой, такая версия останется на диске.

Для небольшого снимка данных на локальной файловой системе Linux удобно сначала подготовить новый файл рядом с основным, закрыть его и затем заменить основной через os.replace. Пример рассчитан на Python 3.8 и новее:

import json
import os
import tempfile
from pathlib import Path

def save_snapshot(path, data):
    target = Path(path)
    fd, name = tempfile.mkstemp(
        dir=target.parent,
        prefix=f".{target.name}."
    )
    temp = Path(name)

    try:
        with os.fdopen(fd, "w", encoding="utf-8") as f:
            json.dump(data, f, ensure_ascii=False, allow_nan=False)
        os.replace(temp, target)
    finally:
        temp.unlink(missing_ok=True)

save_snapshot("status.json", {"temperature": 23.7})

Каталог должен существовать, а у пользователя должны быть права на создание и замену файлов в нём. В примере читатель и писатель работают от одного пользователя: временный файл создаётся с правами 0600. При замене права прежнего status.json автоматически не сохраняются.

allow_nan=False заставляет сериализацию завершиться ошибкой при значениях NaN и бесконечности. Они не входят в стандарт JSON, поэтому прежний корректный снимок в этом случае лучше сохранить.

Временный файл создаётся в том же каталоге, чтобы замена происходила в пределах одной файловой системы. На Linux такая замена атомарна: при открытии status.json читатель получает прежнюю или новую версию. Промежуточного состояния с половиной нового JSON по этому пути нет. При самом первом запуске файла ещё может не быть — этот случай читатель обрабатывает отдельно.

Если читатель открыл старую версию до замены, его файловый дескриптор продолжит ссылаться на неё. Следующее открытие по имени уже даст новый файл.

У приёма есть границы. Два писателя всё ещё могут перезаписать результаты друг друга: последняя замена победит. Для согласования изменений нужна блокировка или другой способ координации. Атомарность также не гарантирует сохранность последней версии после отключения питания: для этого отдельно разбираются синхронизация файла и каталога.

При исключении в Python блок finally удаляет временный файл. После SIGKILL или отключения питания он может остаться в каталоге: finally в таких случаях не выполняется.

Проверка простая: вызвать ошибку сериализации до os.replace и убедиться, что старый снимок читается, а временный файл удалён. Затем выполнить успешное обновление и проверить новый JSON.

Для файла состояния полезное свойство именно такое: пока новый снимок не готов, читателям доступен предыдущий.

Теги:
+1
Комментарии0

Дата‑центры в США начали использовать старые авиационные двигатели на фоне растущих задержек с подключением к энергосети

Некоторые американские центры обработки данных для задач искусственного интеллекта производят собственную электроэнергию с помощью переоборудованных авиационных двигателей, пишет New York Times. Списанные реактивные двигатели вряд ли можно назвать полноценной электростанцией, но их применение свидетельствует о том, насколько сильно энергоснабжение отстаёт от развития сферы ИИ.

Дата‑центры в США начали использовать старые авиационные двигатели на фоне растущих задержек с подключением к энергосети

Публикации