Кратко

  • RFC 9111 требует, чтобы кэш, получивший ответ без ошибки на небезопасный запрос, инвалидировал целевой URI, однако правило действует в кэшах, через которые прошёл этот запрос.
  • Утверждение о глобальной очистке требует отдельных доказательств охвата маршрутов, связанных URI и производных ключей приложения.

Рассмотрим заведомо гипотетический инцидент. Клиент отправляет PUT, источник отвечает 204 No Content, и панель управления сразу объявляет глобальную очистку завершённой. Запись прошла через кэш приложения и один региональный шлюз. Но другой пограничный узел, не лежащий на этом пути, продолжает выдавать страницу подборки, собранную из старого объекта. Статус 204 не указывает ни на этот узел, ни на производный ключ подборки.

Это не изъян HTTP-кэширования. Это граница между правилом протокола и эксплуатационным утверждением. RFC 9110 называет метод безопасным, если его определённая семантика по существу доступна только для чтения; безопасными названы GET, HEAD, OPTIONS и TRACE. Методы, способные изменить состояние, обрабатываются иначе. RFC 9111 требует от кэша передавать небезопасный запрос источнику: кэш не вправе создать ответ до пересылки запроса и получения соответствующего ответа.

Ответ порождает точную обязанность. Получив ответ без ошибки на небезопасный метод, кэш должен инвалидировать целевой URI. Здесь ответ без ошибки означает статус 2xx или 3xx. Инвалидация может удалить совпадающие сохранённые ответы либо пометить их недействительными, чтобы перед повторным использованием требовалась обязательная проверка. Правило не позволяет слепо переиспользовать старый ответ, но не удостоверяет исчезновение каждой копии в системе.

RFC 9111 также разрешает инвалидировать другие URI. Значения Location и Content-Location могут стать кандидатами, если у них тот же источник, что и у целевого URI. Такое разрешение полезно, но не является универсальным механизмом обнаружения зависимостей. Кэш не должен по этому правилу инвалидировать кандидат с другим источником и не обязан выводить все карточки товаров, списки, результаты поиска, фрагменты или суррогатные ключи, созданные приложением из изменённого объекта.

Ещё одну границу задаёт топология. Спецификация прямо отмечает, что механизм не гарантирует глобальную инвалидацию: меняющий состояние запрос инвалидирует ответы только в тех кэшах, через которые он проходит. Кэш на другом пути чтения не получил протокольного события, запускающего его локальную обязанность. Несколько CDN, обход защитного кэша, региональные разделения и разные пути API и страниц превращают это ограничение в задачу управления.

Ошибка возникает, когда соединяют три разных утверждения. «Источник принял запись» относится к ответу. «Кэш на пути инвалидировал целевой URI» относится к обязательному локальному действию. «Теперь каждый читатель увидит новое состояние» относится к топологии, производным ключам и проверке. Первое не доказывает второе на каждом уровне, а вместе они ещё не доказывают третье.

Пробел можно закрыть квитанцией маршрута инвалидации. Это предложенная здесь редакционная конструкция контроля, а не объект протокола, определённый IETF. Квитанция связывает небезопасный запрос и ответ с экземплярами кэша, которые их переносили; фиксирует нормализованный целевой URI и локальное действие; отделяет обязательную инвалидацию цели от необязательной обработки Location или Content-Location; прикладывает карту списков, поиска, фрагментов и суррогатных ключей; сохраняет результаты обходящих кэш проб с каждого существенного пути доставки.

После успешной записи вопрос меняется. 204 больше не считается глобальным событием кэша. Нужно установить, какой путь перенёс запись, какой кэш сработал, какие идентификаторы охвачены и какие независимые чтения подтвердили новое состояние. Только тогда локальное действие по протоколу становится доказательством утверждения обо всей системе.

Источники