Таймаут описывает знание клиента, а не итог операции
В вымышленной системе клиент попросил сформировать отчёт с меткой намерения Р17. Сервер создал задание номер семьдесят три, но ответ потерялся по дороге. Клиент видит неопределённый исход, хотя действие уже произошло. Если теперь послать новое намерение с другой меткой, система может создать ещё одно задание. Проблема возникает не потому, что два отчёта отличаются содержанием, а потому, что серверу сообщили о двух независимых операциях. Одинаковые параметры сами по себе не всегда означают одинаковое намерение пользователя.
Ключ повтора должен сохранять смысл действия
В нашей модели договор предусматривает ключ идемпотентности: повтор того же намерения с теми же параметрами связывается с уже зарегистрированным действием. Поэтому клиент сохраняет метку Р17 при разрешённом повторе, а сервер возвращает сведения о задании номер семьдесят три вместо создания нового. Термин идемпотентность здесь относится к эффекту повторения по установленному договору. Он не означает, что любое действие любого сервиса можно бесконечно повторять или что достаточно просто добавить произвольное поле к запросу.
Одной записи ключа после выполнения недостаточно
Представим, что два одинаковых запроса пришли почти одновременно. Если каждый успеет проверить отсутствие ключа до того, как другой его сохранит, оба могут начать работу. Поэтому серверу необходима согласованная обработка регистрации намерения и выполнения действия. Также нужно определить, что возвращать, пока исходная операция ещё выполняется. Конкретный способ зависит от архитектуры и хранилища. Бумажная модель не выбирает готовую реализацию, но показывает требование: конкурентные повторы не должны свободно превращаться в независимые создания одного и того же результата.
Срок хранения и параметры являются частью договора
Защита повтора может действовать ограниченное время. Если запись о ключе удалена, поздний запрос способен рассматриваться как новый. Также нельзя сохранять старую метку и незаметно менять смысл действия, например другой период отчёта: серверу требуется правило обработки такого несоответствия. До повторения клиенту важно знать поддерживаемые гарантии и доступный способ проверить состояние. Идемпотентность снижает риск дублирования в определённых условиях, но не отменяет обработку ошибок, наблюдение за исходом и ограничения нагрузки на систему.
Попробуйте на практике
Проследите судьбу одного вымышленного отчёта в бумажном журнале событий.
- Запишите: клиент отправил намерение Р17, сервер создал задание семьдесят три, ответ не дошёл. Разделите фактическое состояние сервера и сведения, которыми располагает клиент.
- Добавьте повтор с тем же ключом и теми же параметрами в пределах срока хранения. По условиям модели укажите уже существующее задание, не создавая второе.
- Рассмотрите отдельный вариант с новой меткой Р18. Объясните, почему сервер может воспринять его как новое намерение, даже если параметры отчёта похожи.
- Добавьте два вопроса к архитектуре: как обрабатываются одновременные повторы и что происходит после окончания срока хранения ключа. Не подменяйте отсутствие этих правил словом безопасно.
Как проверить результат. Потерянный ответ не принят за доказанный провал. В варианте с сохранённым намерением остаётся одно задание, а новая метка отмечена как возможная новая операция. Границы серверного договора названы явно.
Частые вопросы
Любой повтор с одинаковым текстом запроса идемпотентен?
Нет. Одинаковые данные могут относиться к разным намерениям. Гарантия зависит от операции и того, как сервер распознаёт и обрабатывает её повторение.
Ключ позволяет игнорировать дальнейший статус?
Нет. Нужно различать регистрацию запроса, выполнение задания и подтверждённый результат. Защита от дубликатов не доказывает, что полезная работа уже завершилась успешно.
Самостоятельный разбор темы. Содержание конкретной обучающей программы здесь не представлено.