Re[30]: Идемпотентность POST - хорошая ли практика?
От: vsb Казахстан  
Дата: 02.10.22 19:07
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Вот у нас есть три клиента — A, B, С,


S>1. A создаёт объект X.

S>2. B находит объект X, и модифицирует его (назовём новое состояние X').
S>3. С находит объект X' и удаляет его.

S>Теперь представим, что у всех троих нестабильная связь. Очевидно, что A должен иметь возможность повторять попытки создать X и после момента 2, и после момента 3.

S>При этом мы ожидаем, что он таки получит свой 201 — c его точки зрения, это первая успешная попытка создания.
S>Чего мы не ожидаем:
S>- что после 2 он получит 4хх — это бы выглядело так, как будто он сделал что-то нехорошее (пытается создать объект-дубликат)

Не вижу в этом проблем. Любая достаточно большая распределённая система постоянно работает с ошибками. Это её нормальное состояние. Любой компонент получает ошибки. Везде есть какие-то баги. Никто не ставит алярмы на единственный HTTP 400. Алярмы ставят, когда ошибок становится больше ожидаемого процента.

То бишь в описанной ситуации A при повторе получает ошибку 400, логгирует её и успокаивается. При этом если для него важно как-то проверять после создания, есть ли объект — он должен сделать GET или подобный запрос и дальше уже работать исходя из этого.

B и C так же получают ошибку и так же примерно с ней работают.

Учитывая, что вероятность этой ошибки невелика, проблем это не вызывает. Главное, чтобы каждый компонент работал устойчиво при наличии этих ошибок.
Re[32]: Идемпотентность POST - хорошая ли практика?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.10.22 19:42
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>В том-то и дело, что в спеке неявно подразумевается, что клиент — единственный, кто взаимодействует с заданным ресурсом на сервере.

Я так не думаю. Неглупые люди писали спеку, в первым автором вообще-то филдинг числится.
Если в спеке не закладывалась идея "сильной идемпотентности", то есть с сохранением порядка запросов, то, видимо, или другие способы обеспечения есть, или "овчинка не стоит выделки".


G>>Все что необходимо для решения проблемы конкурентного обновления есть в https://httpwg.org/specs/rfc9110.html

G>>Даже два механизма:
G>>- заголовок ответа Last-Modified и изголовки запросов If-Modified-Since, If-Unmodifieed-Since
G>>- заголовок ответа Etag и изголовки запросов If-Match, If-None-Match
G>>Предполагается что в случае невыполнения условия сервер должен вернуть 412 Precondition Failed
S>Это нарушает ожидания от "сильной идемпотентности". И даже с этими хидерами у нас нет никакой гарантии соблюдения идемпотентности в случае взаимодействия с сервером нескольких клиентов.
S>Попробуйте "починить" приведённый мной пример при помощи добавления этих заголовков в запросы и ответы.
S>Парочку из аномалий вы предотвратите, но не все.

По факту остается только одна проблема, если повторно выполнить PUT с If-None-Match: *, то будет 412 если предыдущая попытка была успешна, но мы не получили ответ.
С другой стороны в этом запросе 412 однозначно трактуется как "запись с этим ключом уже существует" и приложение может продолжать выполнение опираясь на это факт.
Re[34]: Идемпотентность POST - хорошая ли практика?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.10.22 19:59
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Для конкретики: А1 — это списание денег, А2 — резервирование авиабилета.

S>Z ничего не знает про деньги; его работа — чисто резервирование билетов от имени агента.
S>Y ничего не знает про билеты; его работа — чисто обработка платежей.

Тут мы попадаем на CAP теорему.
Это означает что нам нужно требовать отсутствие разделения, то есть утверждать, что пропадания связи с А1 и А2 или будут совсем отсутствовать, или будут заранее ограничены. Тогда мы можем сделать свой координатор, который будет принимать одним запросом данные билетах и платежах, а сам будет организовывать повторы столько раз сколько необходимо, даже с учетом перезагрузки самого координатора.
Re[34]: Идемпотентность POST - хорошая ли практика?
От: · Великобритания  
Дата: 02.10.22 20:46
Оценка: 10 (1)
Здравствуйте, Sinclair, Вы писали:

S>Важно не наличие прокси, а сама возможность восстановить когерентность состояния после сбоя.

Для меня прокси как умственный констркут, позволяющий мыслить как операции работают, упрощают понимание сути.
Т.е. вместо того, чтобы мучиться рассуждениями как должен себя вести сервер при получении дубликатов — просто можно считать, что до сервера дубликаты не доходят, а этим занимается прокси. Иными словами, вместо одного сверхумного компонента, рассматриваем два простых — тупой сервер который умеет обрабатывать один запрос без повторов и кеш который тупо возвращает то что видел.

S>Вот у вас есть микросервис Х, который выставляет наружу некоторую операцию A.

S>Для выполнения этой операции нужно выполнить две операции — A1 и A2, в микросервисах Y и Z.
По-моему ты ожидаешь от идемпотентности больше, чем положено. Идемпотентность про одну операцию, а не про их взаимодействие. (вспомни формулу f ∘ f = f — там нет никаких A,Y,Z, ровно одна функция).

S>Для конкретики: А1 — это списание денег, А2 — резервирование авиабилета.

S>Z ничего не знает про деньги; его работа — чисто резервирование билетов от имени агента.
S>Y ничего не знает про билеты; его работа — чисто обработка платежей.
А это всё разруливается бизнес-логикой и универсального решения нет. Ну и CAP подлянки подстраивает.
Например, типично делают временную блокировку билета (скажем на 15 минут) в течение которой должна пройти успешно оплата. После этого уже резервирование билета.
Притом, в случае технической проблемы (всё упало, и после оплаты не удалось уложиться в 15 минут завершить резервацию), то предусматривают ручную утряску или возврат денег.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[31]: Идемпотентность POST - хорошая ли практика?
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.10.22 02:57
Оценка:
Здравствуйте, vsb, Вы писали:
vsb>Не вижу в этом проблем.
А зря.
vsb>Любая достаточно большая распределённая система постоянно работает с ошибками. Это её нормальное состояние. Любой компонент получает ошибки. Везде есть какие-то баги. Никто не ставит алярмы на единственный HTTP 400. Алярмы ставят, когда ошибок становится больше ожидаемого процента.
Дело не в алярме, а в восстановлении после сбоя. Получить 200 ок, когда на самом деле API Call упал — ничуть не хуже, чем получить 4хх, когда он на самом деле сработал.

vsb>То бишь в описанной ситуации A при повторе получает ошибку 400, логгирует её и успокаивается. При этом если для него важно как-то проверять после создания, есть ли объект — он должен сделать GET или подобный запрос и дальше уже работать исходя из этого.

Вот наш клиент позвал метод "перевести деньги", получил 4хх. Ок, у нас есть автоматизированная схема "попробовать следующий метод платежа".
Попробовал — получил 200, пометил у себя "всё ок, я оплатил заказ". В итоге продавцу деньги ушли дважды, и поймаем мы это только через месяцок, когда будем сверять баланс счёта.

vsb>B и C так же получают ошибку и так же примерно с ней работают.

Неа.

vsb>Учитывая, что вероятность этой ошибки невелика, проблем это не вызывает. Главное, чтобы каждый компонент работал устойчиво при наличии этих ошибок.

Вызывает Невозможно обеспечить "устойчивую работу", если для этого не предложено средств.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[35]: Идемпотентность POST - хорошая ли практика?
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.10.22 03:02
Оценка: +1
Здравствуйте, ·, Вы писали:
·>Т.е. вместо того, чтобы мучиться рассуждениями как должен себя вести сервер при получении дубликатов — просто можно считать, что до сервера дубликаты не доходят, а этим занимается прокси. Иными словами, вместо одного сверхумного компонента, рассматриваем два простых — тупой сервер который умеет обрабатывать один запрос без повторов и кеш который тупо возвращает то что видел.
Можно, но это никак не поможет рассуждать о корректности. В описанном сценарии прокси между A/B/C и сервисах ничего не изменят — по-прежнему состояние сервера будет разрушено, хотя каждый из клиентов всё делал безупречно.

·>По-моему ты ожидаешь от идемпотентности больше, чем положено. Идемпотентность про одну операцию, а не про их взаимодействие. (вспомни формулу f ∘ f = f — там нет никаких A,Y,Z, ровно одна функция).

Я иду с другой стороны. У меня нет задачи "о, прикольная штука эта ваша идемпотентность, к чему бы полезному её пристроить". У меня задача — ровно наоборот: спроектировать и реализовать API, который позволяет написать к нему клиентов, которые смогут корректно работать при наличии сбоев.

·>А это всё разруливается бизнес-логикой и универсального решения нет.

Если мы придумаем решение для этой конкретной бизнес-логики, то оно легко станет универсальным.
·>Ну и CAP подлянки подстраивает.
Нет, CAP тут ни при чём.
·>Например, типично делают временную блокировку билета (скажем на 15 минут) в течение которой должна пройти успешно оплата. После этого уже резервирование билета.
Это вообще не решение. Вот у нас оплата успешно прошла, но клиент об этом не узнал. Дальше что?
·>Притом, в случае технической проблемы (всё упало, и после оплаты не удалось уложиться в 15 минут завершить резервацию), то предусматривают ручную утряску или возврат денег.
Ну вот я и хочу избавиться от ручной утряски — это очень дорогостоящая процедура.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[35]: Идемпотентность POST - хорошая ли практика?
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.10.22 03:05
Оценка:
Здравствуйте, gandjustas, Вы писали:
G>Тут мы попадаем на CAP теорему.
Не вижу её применимости.
G>Это означает что нам нужно требовать отсутствие разделения, то есть утверждать, что пропадания связи с А1 и А2 или будут совсем отсутствовать, или будут заранее ограничены. Тогда мы можем сделать свой координатор, который будет принимать одним запросом данные билетах и платежах, а сам будет организовывать повторы столько раз сколько необходимо, даже с учетом перезагрузки самого координатора.
Нет конечно. CAP — очень убогая штука, она оперирует слишком ограниченными определениями.
В нашем случае достаточно понимать, что по мере повторных выполнений идемпотентных запросов вероятность продолжить некогерентность падает экспоненциально быстро.
Грубо говоря, 90% запросов будут обработаны с одного раза.
9% потребуют одного повтора.
<1 потребуют трёх повторов.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[36]: Идемпотентность POST - хорошая ли практика?
От: · Великобритания  
Дата: 03.10.22 09:36
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

S>·>Т.е. вместо того, чтобы мучиться рассуждениями как должен себя вести сервер при получении дубликатов — просто можно считать, что до сервера дубликаты не доходят, а этим занимается прокси. Иными словами, вместо одного сверхумного компонента, рассматриваем два простых — тупой сервер который умеет обрабатывать один запрос без повторов и кеш который тупо возвращает то что видел.

S>Можно, но это никак не поможет рассуждать о корректности. В описанном сценарии прокси между A/B/C и сервисах ничего не изменят — по-прежнему состояние сервера будет разрушено, хотя каждый из клиентов всё делал безупречно.
Не очень ясно причём тут идемпотентность тогда. Идемпотентность никак не помогает рассуждать о корректности взаимодействия между множеством систем, только между двумя. Именно между двумя системами происходит State Transfer.

S>·>По-моему ты ожидаешь от идемпотентности больше, чем положено. Идемпотентность про одну операцию, а не про их взаимодействие. (вспомни формулу f ∘ f = f — там нет никаких A,Y,Z, ровно одна функция).

S>Я иду с другой стороны. У меня нет задачи "о, прикольная штука эта ваша идемпотентность, к чему бы полезному её пристроить". У меня задача — ровно наоборот: спроектировать и реализовать API, который позволяет написать к нему клиентов, которые смогут корректно работать при наличии сбоев.
Так это уже CAP.

S>·>А это всё разруливается бизнес-логикой и универсального решения нет.

S>Если мы придумаем решение для этой конкретной бизнес-логики, то оно легко станет универсальным.
S>·>Ну и CAP подлянки подстраивает.
S>Нет, CAP тут ни при чём.
Именно причём. У тебя происходит Partitioning (между клиентом и сервером произошел разрыв связи) и бизнес должен решить, чем жертвовать C или A.

S>·>Например, типично делают временную блокировку билета (скажем на 15 минут) в течение которой должна пройти успешно оплата. После этого уже резервирование билета.

S>Это вообще не решение. Вот у нас оплата успешно прошла, но клиент об этом не узнал. Дальше что?
Оплата прошла, билет куплен успешно. Если у клиент об этом не узнал (мобильник выпал из рук и разбился), то это забота клиента найти способ связаться и узнать о результате.

S>·>Притом, в случае технической проблемы (всё упало, и после оплаты не удалось уложиться в 15 минут завершить резервацию), то предусматривают ручную утряску или возврат денег.

S>Ну вот я и хочу избавиться от ручной утряски — это очень дорогостоящая процедура.
А есть варианты? И, главное, причём тут идемпотентность?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[37]: Идемпотентность POST - хорошая ли практика?
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.10.22 11:15
Оценка:
Здравствуйте, ·, Вы писали:

·>Не очень ясно причём тут идемпотентность тогда. Идемпотентность никак не помогает рассуждать о корректности взаимодействия между множеством систем, только между двумя. Именно между двумя системами происходит State Transfer.

Ну так у нас взаимодействие всегда происходит между двумя системами. Я же вроде очень подробно пример расписал. Непонятно, что вам непонятно

·>Так это уже CAP.

Нет. CAP — это некий удобный акроним, на который можно списать всё, что угодно. Утекли деньги со счёта — "это CAP виновата ". Нет, это так не работает.


·>Именно причём. У тебя происходит Partitioning (между клиентом и сервером произошел разрыв связи) и бизнес должен решить, чем жертвовать C или A.

Ок, я выбираю пожертвовать A (хотя это опять ложная дилемма — A не является бинарной величиной). Верните мне мою C.

·>Оплата прошла, билет куплен успешно. Если у клиент об этом не узнал (мобильник выпал из рук и разбился), то это забота клиента найти способ связаться и узнать о результате.

Не мобильник выпал и разбился, а VM была перезапущена в рамках стандартного failover. Клиент — это серверный процесс. Как именно вы предлагаетее ему "связаться и узнать о результатах"?

иться в 15 минут завершить резервацию), то предусматривают ручную утряску или возврат денег.
S>>Ну вот я и хочу избавиться от ручной утряски — это очень дорогостоящая процедура.
·>А есть варианты? И, главное, причём тут идемпотентность?
Конечно есть. Вариант — обеспечить идемпотентность запросов. Даже в случае возможных конкурирующих запросов от других клиентов.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[36]: Идемпотентность POST - хорошая ли практика?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 03.10.22 12:12
Оценка: 5 (1) +3
Здравствуйте, Sinclair, Вы писали:

S>В нашем случае достаточно понимать, что по мере повторных выполнений идемпотентных запросов вероятность продолжить некогерентность падает экспоненциально быстро.

S>Грубо говоря, 90% запросов будут обработаны с одного раза.
S>9% потребуют одного повтора.
S><1 потребуют трёх повторов.
В описано сценарии надо еще и отказ обрабатывать:
1) Если бронь не прошла, то надо откатить оплату
2) Если оплата не прошла, то надо откатить бронь
3) Тот кто отправляет запросы может перезагрузиться в любой момент и при этом должно отработать все корректно
И при этом на каждом шаге еще и может возникнуть необходимость повторов.

В общем это очень сложная задача. И она очень похожа на "задачу о двух генералах".

Поэтому в реальности бронирование билетов происходит таким образом:
1) После выбора билетов клиентом сразу отправляется предварительная бронь, она держится от 5 от 30 минут
2) За этим 5-30 минут клиент должен выбрать опции и способ оплаты. В это время никто другой не может взаимодействовать с забронированными местами.
3) После оплаты отправляется подтверждение сервису бронирования. Причем сразу по двум путям — одно от клиента с кодом оплаты, второе отправляет сам платежный сервер в систему бронирования. Если получено подтверждение интерактивным путем, то клиент сразу получает билет, если фоновым, то отправляется на почту (обычно происходит оба варианта).
4) Если подтверждение до сервера бронирования так и не дошло за 5-30 минут, то то сервер пытается отменить оплаты по код бронирования.

Такой сценарий полностью исключает состояние гонки при бронировании и описанные выше проблемы становятся неактуальными.
Предполагает сто связь неустойчива между всеми узлами, вплоть до того, что связь может отсутствовать неограниченно долго.

Я думаю те, кто писали спеку 9110 прекрасно понимали сложность систем с повторами и порядком доставки сообщений, поэтому не включали в понятие идемпотентности сохранение порядка запросов, ибо во многих случаях это сложная, но мало чего дает клиенту.
Re[38]: Идемпотентность POST - хорошая ли практика?
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 03.10.22 12:18
Оценка:
Здравствуйте, Sinclair, Вы писали:


S>·>Так это уже CAP.

S>Нет. CAP — это некий удобный акроним, на который можно списать всё, что угодно. Утекли деньги со счёта — "это CAP виновата ". Нет, это так не работает.
CAP это проблема, которую должен решать программист. При наличии признаков CAP надо понимать что при потере связи система будет терять согласованность или доступность.
И надо будет что-то делать, чтобы не терять.
Или увеличивать надежность сетевых соединений, уменьшая время потери доступности, или вносить в систему механизм восстановления согласованности, если часть сообщений потерялась.
В простых случаях механизм восстановления согласованности может быть тупым — повторять запросы, пока что-нибудь не вернет. Но часто оказывается сложнее, примерно как при покупке билетов, который я описал выше.
Отредактировано 03.10.2022 13:13 gandjustas . Предыдущая версия .
Re[38]: Идемпотентность POST - хорошая ли практика?
От: · Великобритания  
Дата: 03.10.22 12:56
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>·>Не очень ясно причём тут идемпотентность тогда. Идемпотентность никак не помогает рассуждать о корректности взаимодействия между множеством систем, только между двумя. Именно между двумя системами происходит State Transfer.

S>Ну так у нас взаимодействие всегда происходит между двумя системами. Я же вроде очень подробно пример расписал. Непонятно, что вам непонятно
Да. Но ты хочешь добиться каких-то гарантий между 2+ систем. Partitioning мешается.

S>·>Так это уже CAP.

S>Нет. CAP — это некий удобный акроним, на который можно списать всё, что угодно. Утекли деньги со счёта — "это CAP виновата ". Нет, это так не работает.
Не совсем. CAP диктует какие сценарии возможны. А это уже дело BA определить поведение адекватное с т.з. бизнеса в таких сценариях.

S>·>Именно причём. У тебя происходит Partitioning (между клиентом и сервером произошел разрыв связи) и бизнес должен решить, чем жертвовать C или A.

S>Ок, я выбираю пожертвовать A (хотя это опять ложная дилемма — A не является бинарной величиной). Верните мне мою C.
Ну в рассамтриваемом примере это означает, что самолёт никуда не полетит (no Availability) пока каждый из заказов не подвердится/отклонится каждым из клиентов.

S>·>Оплата прошла, билет куплен успешно. Если у клиент об этом не узнал (мобильник выпал из рук и разбился), то это забота клиента найти способ связаться и узнать о результате.

S>Не мобильник выпал и разбился, а VM была перезапущена в рамках стандартного failover. Клиент — это серверный процесс.
Да без разницы, человек это или vm. failover может перезапустить процесс, но что-то опять может пойти не так. Место на диске закончилось, например, и процесс застрял. А админы спят, диск почистить некому, самолёт готовится к вылету. Шо делать?

S>Как именно вы предлагаетее ему "связаться и узнать о результатах"?

Или я вопрос не понял?..

S>иться в 15 минут завершить резервацию), то предусматривают ручную утряску или возврат денег.

S>>>Ну вот я и хочу избавиться от ручной утряски — это очень дорогостоящая процедура.
S>·>А есть варианты? И, главное, причём тут идемпотентность?
S>Конечно есть. Вариант — обеспечить идемпотентность запросов. Даже в случае возможных конкурирующих запросов от других клиентов.
Как это поможет в случае "клиент об этом не узнал"?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[39]: Идемпотентность POST - хорошая ли практика?
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.10.22 13:43
Оценка:
Здравствуйте, ·, Вы писали:

·>Да. Но ты хочешь добиться каких-то гарантий между 2+ систем. Partitioning мешается.

Нет, не мешается.

·>Не совсем. CAP диктует какие сценарии возможны. А это уже дело BA определить поведение адекватное с т.з. бизнеса в таких сценариях.

Не совсем. Полезность CAP примерно равна нулю. Потому, что её терминология не соответствует примерно ничему в инженерии.

·>Ну в рассамтриваемом примере это означает, что самолёт никуда не полетит (no Availability) пока каждый из заказов не подвердится/отклонится каждым из клиентов.

Ничего подобного. В рассматриваемом примере это означает, что самолёт улетит без пассажира. И рано или поздно клиент сервиса получит информацию о том, что так произошло, после чего сможет корректным образом отменить перевод денег. Зачем вы пишете ерунду?

·>Да без разницы, человек это или vm. failover может перезапустить процесс, но что-то опять может пойти не так. Место на диске закончилось, например, и процесс застрял. А админы спят, диск почистить некому, самолёт готовится к вылету. Шо делать?

Ну, а вы как думаете?

S>>Как именно вы предлагаетее ему "связаться и узнать о результатах"?

·>Или я вопрос не понял?..
Мне отсюда не видно, поняли вы или нет. Как именно процесс-клиент должен связываться и узнавать о результатах запроса, ответ на который он не получил — потому что сам был рестартован, или потому что при коммуникации возник сбой, или потому что он получил 500 и не имеет понятия, успел ли сервер внести изменения на своей стороне перед тем, как упасть и ответить 500.
S>>Конечно есть. Вариант — обеспечить идемпотентность запросов. Даже в случае возможных конкурирующих запросов от других клиентов.
·>Как это поможет в случае "клиент об этом не узнал"?
Очень просто: клиент рано или поздно узнАет результат.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[40]: Идемпотентность POST - хорошая ли практика?
От: · Великобритания  
Дата: 03.10.22 14:02
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>·>Не совсем. CAP диктует какие сценарии возможны. А это уже дело BA определить поведение адекватное с т.з. бизнеса в таких сценариях.

S>Не совсем. Полезность CAP примерно равна нулю. Потому, что её терминология не соответствует примерно ничему в инженерии.
Это соответствует бизнес-процессам. Дело инженера лишь объяснить бизнес-аналисту суть ограничений, накладываемых теоремой.

S>·>Ну в рассамтриваемом примере это означает, что самолёт никуда не полетит (no Availability) пока каждый из заказов не подвердится/отклонится каждым из клиентов.

S>Ничего подобного. В рассматриваемом примере это означает, что самолёт улетит без пассажира. И рано или поздно клиент сервиса получит информацию о том, что так произошло, после чего сможет корректным образом отменить перевод денег. Зачем вы пишете ерунду?
Это означает, что самолёт улетит с пустым местом и авиакомпания потеряет деньги. А так бы место могли продать кому-то другому, но место было отмечено как занятое, никто не полетел, деньги не списались, обед пошел в мусор. Нарушение Consistency.

S>·>Да без разницы, человек это или vm. failover может перезапустить процесс, но что-то опять может пойти не так. Место на диске закончилось, например, и процесс застрял. А админы спят, диск почистить некому, самолёт готовится к вылету. Шо делать?

S>Ну, а вы как думаете?
Наказать невиновных, наградить непричастных. А больше ничего не сделаешь.

S>>>Как именно вы предлагаетее ему "связаться и узнать о результатах"?

S>·>Или я вопрос не понял?..
S>Мне отсюда не видно, поняли вы или нет. Как именно процесс-клиент должен связываться и узнавать о результатах запроса, ответ на который он не получил — потому что сам был рестартован, или потому что при коммуникации возник сбой, или потому что он получил 500 и не имеет понятия, успел ли сервер внести изменения на своей стороне перед тем, как упасть и ответить 500.
Послать запрос опять и обработать результат. Что должно произойти на сервере — понять просто: преставсь себе, что до сервера повторный запрос не дойдёт, а ответит прокси из кеша.

S>>>Конечно есть. Вариант — обеспечить идемпотентность запросов. Даже в случае возможных конкурирующих запросов от других клиентов.

S>·>Как это поможет в случае "клиент об этом не узнал"?
S>Очень просто: клиент рано или поздно узнАет результат.
Т.е. теряется consistency. Клиент, пока не узнал результат, находится в некосистентном с сервером состоянии — у клиента состояние "неизвестно" у сервера "зарезервировано". Опять CAP.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[41]: Идемпотентность POST - хорошая ли практика?
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.10.22 14:15
Оценка:
Здравствуйте, ·, Вы писали:

·>Здравствуйте, Sinclair, Вы писали:


S>>·>Не совсем. CAP диктует какие сценарии возможны. А это уже дело BA определить поведение адекватное с т.з. бизнеса в таких сценариях.

S>>Не совсем. Полезность CAP примерно равна нулю. Потому, что её терминология не соответствует примерно ничему в инженерии.
·>Это соответствует бизнес-процессам. Дело инженера лишь объяснить бизнес-аналисту суть ограничений, накладываемых теоремой.
Нет там никаких особенных ограничений. Вот вы сейчас играете за инженера, а я — за BA. Вот вы мне объяснили, что C и A невозможны одновременно. Я вам в ответ — ок, я согласен на A = 99.99%. Какая С у вас получится при таком допущении?

·>Это означает, что самолёт улетит с пустым местом и авиакомпания потеряет деньги.

·>А так бы место могли продать кому-то другому, но место было отмечено как занятое, никто не полетел, деньги не списались, обед пошел в мусор. Нарушение Consistency.
Деньги как раз списались. Если деньги не списались — то и проблемы нет: точно так же, как и в предлагаемом вами варианте, резервация слетела по времени. А вот если списались, то неявка на рейс — проблема пассажира.
Тем более, что у него остаётся ещё N часов до собственно вылета, чтобы всё же получить заветную квитанцию после N retry.

S>>·>Да без разницы, человек это или vm. failover может перезапустить процесс, но что-то опять может пойти не так. Место на диске закончилось, например, и процесс застрял. А админы спят, диск почистить некому, самолёт готовится к вылету. Шо делать?

S>>Ну, а вы как думаете?
·>Наказать невиновных, наградить непричастных. А больше ничего не сделаешь.
Понятно. Нет, меня не устраивает.

S>>Мне отсюда не видно, поняли вы или нет. Как именно процесс-клиент должен связываться и узнавать о результатах запроса, ответ на который он не получил — потому что сам был рестартован, или потому что при коммуникации возник сбой, или потому что он получил 500 и не имеет понятия, успел ли сервер внести изменения на своей стороне перед тем, как упасть и ответить 500.

·>Послать запрос опять и обработать результат. Что должно произойти на сервере — понять просто: преставсь себе, что до сервера повторный запрос не дойдёт, а ответит прокси из кеша.
Ну, так мы и вернулись к вопросу идемпотентности. Прокси-то ответит не то, что стало с ресурсом теперь, когда его потрогали другие клиенты. Он вернёт из кэша ровно тот же 200 Ok, что сервер отдал ещё при первой попытке.

S>>Очень просто: клиент рано или поздно узнАет результат.

·>Т.е. теряется consistency. Клиент, пока не узнал результат, находится в некосистентном с сервером состоянии — у клиента состояние "неизвестно" у сервера "зарезервировано". Опять CAP.
Не надо пытаться отмазаться от решения инженерных задач, кивая на CAP. CAP, собственно, заканчивается на том, что "невозможно достучаться до отключенного узла".
Проблема не-идемпотентных подходов — ровно в том, что у них нет способа вернуться к консистентности даже после окончания partition.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[42]: Идемпотентность POST - хорошая ли практика?
От: · Великобритания  
Дата: 03.10.22 15:45
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>>>Не совсем. Полезность CAP примерно равна нулю. Потому, что её терминология не соответствует примерно ничему в инженерии.

S>·>Это соответствует бизнес-процессам. Дело инженера лишь объяснить бизнес-аналисту суть ограничений, накладываемых теоремой.
S>Нет там никаких особенных ограничений. Вот вы сейчас играете за инженера, а я — за BA. Вот вы мне объяснили, что C и A невозможны одновременно. Я вам в ответ — ок, я согласен на A = 99.99%. Какая С у вас получится при таком допущении?
Не очень понял что этот процент значит в контексте CAP.

S>·>Это означает, что самолёт улетит с пустым местом и авиакомпания потеряет деньги.

S>·>А так бы место могли продать кому-то другому, но место было отмечено как занятое, никто не полетел, деньги не списались, обед пошел в мусор. Нарушение Consistency.
S>Деньги как раз списались. Если деньги не списались — то и проблемы нет: точно так же, как и в предлагаемом вами варианте, резервация слетела по времени. А вот если списались, то неявка на рейс — проблема пассажира.
S>Тем более, что у него остаётся ещё N часов до собственно вылета, чтобы всё же получить заветную квитанцию после N retry.
Ты меня запутал в сценариях.
Если сценарий — деньги списались, но не удалось в течение 15 минут завершить резервацию, сервер упал, то извиняемся перед клиентом и возвращаем деньги. Проблема в том, что деньги будут возвращены только после 15 минут+время на восстановление упавшего сервера и успешной отправки инструкции отмены списания денег. И это нарушение availability, т.к. у клиента будет минус на счету и ему может не хватить денег на покупку нового билета.
Если сценарий — деньги списались, резервирование завершилось, но клиент про это не смог узнать (т.к. всё легло) и пропустил рейс, то тоже проблема. Нарушение consistency.

S>>>·>Да без разницы, человек это или vm. failover может перезапустить процесс, но что-то опять может пойти не так. Место на диске закончилось, например, и процесс застрял. А админы спят, диск почистить некому, самолёт готовится к вылету. Шо делать?

S>>>Ну, а вы как думаете?
S>·>Наказать невиновных, наградить непричастных. А больше ничего не сделаешь.
S> Понятно. Нет, меня не устраивает.
А какие варианты-то?

S>>>Мне отсюда не видно, поняли вы или нет. Как именно процесс-клиент должен связываться и узнавать о результатах запроса, ответ на который он не получил — потому что сам был рестартован, или потому что при коммуникации возник сбой, или потому что он получил 500 и не имеет понятия, успел ли сервер внести изменения на своей стороне перед тем, как упасть и ответить 500.

S>·>Послать запрос опять и обработать результат. Что должно произойти на сервере — понять просто: преставсь себе, что до сервера повторный запрос не дойдёт, а ответит прокси из кеша.
S>Ну, так мы и вернулись к вопросу идемпотентности. Прокси-то ответит не то, что стало с ресурсом теперь, когда его потрогали другие клиенты. Он вернёт из кэша ровно тот же 200 Ok, что сервер отдал ещё при первой попытке.
Запросом клиента будет "деньги списались, резервирование завершилось?" — ответ будет OK хоть год спустя. Или я не понял которую операцию ты имеешь в виду. В твоём сценарии будет несколько операций.

S>>>Очень просто: клиент рано или поздно узнАет результат.

S>·>Т.е. теряется consistency. Клиент, пока не узнал результат, находится в некосистентном с сервером состоянии — у клиента состояние "неизвестно" у сервера "зарезервировано". Опять CAP.
S>Не надо пытаться отмазаться от решения инженерных задач, кивая на CAP. CAP, собственно, заканчивается на том, что "невозможно достучаться до отключенного узла".
S>Проблема не-идемпотентных подходов — ровно в том, что у них нет способа вернуться к консистентности даже
Согласен, идемпотентность нужна для обеспечения консистентности. Но мы, вроде, говорим о сценарии, который состоит из множества операций. Идемпотентность каждой из операции никакой магии не сделает и CAP обойти не сможет.

S>после окончания partition.

Т.е. при отсутствии Partition мы можем наконец-то получить Consistency и Availabilty. Ну да, всё в соответствии с теоремой.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[43]: Идемпотентность POST - хорошая ли практика?
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.10.22 16:22
Оценка:
Здравствуйте, ·, Вы писали:

·>Не очень понял что этот процент значит в контексте CAP.

В контексте CAP — ничего не значит. Именно поэтому она полезна примерно никак. Инженеры не измеряют доступность в терминах "есть/нету". Доступность в reliability engineering — это доля успешно обслуженных запросов.

·>Если сценарий — деньги списались, но не удалось в течение 15 минут завершить резервацию, сервер упал, то извиняемся перед клиентом и возвращаем деньги. Проблема в том, что деньги будут возвращены только после 15 минут+время на восстановление упавшего сервера и успешной отправки инструкции отмены списания денег. И это нарушение availability, т.к. у клиента будет минус на счету и ему может не хватить денег на покупку нового билета.

·>Если сценарий — деньги списались, резервирование завершилось, но клиент про это не смог узнать (т.к. всё легло) и пропустил рейс, то тоже проблема. Нарушение consistency.
А если сценарий — деньги списались один раз, но резервирований произошло два (или N) — это нарушение чего? Без идемпотентности вы не сможете достичь даже at most once.

·>А какие варианты-то?

Варианты — постараться автоматически вернуть согласованность после окончания partition.

S>>Ну, так мы и вернулись к вопросу идемпотентности. Прокси-то ответит не то, что стало с ресурсом теперь, когда его потрогали другие клиенты. Он вернёт из кэша ровно тот же 200 Ok, что сервер отдал ещё при первой попытке.

·>Запросом клиента будет "деньги списались, резервирование завершилось?" — ответ будет OK хоть год спустя. Или я не понял которую операцию ты имеешь в виду. В твоём сценарии будет несколько операций.
Чтобы это было "ок хоть год спустя", как раз и нужна идемпотентность. Иначе получается так, что прокси бы ответил "200 Ok", а сервер при вопросе напрямую — "409 conflict", потому что бронирование перестало быть актуальным.

·>Согласен, идемпотентность нужна для обеспечения консистентности. Но мы, вроде, говорим о сценарии, который состоит из множества операций. Идемпотентность каждой из операции никакой магии не сделает и CAP обойти не сможет.

Нам не нужно обходить CAP. Нам нужно максимизировать A и C.
S>>после окончания partition.
·>Т.е. при отсутствии Partition мы можем наконец-то получить Consistency и Availabilty. Ну да, всё в соответствии с теоремой.
При отcутствии "сильной идемпотентности" у нас Consistency и Availability не достигаются даже после окончания Partition.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[44]: Идемпотентность POST - хорошая ли практика?
От: · Великобритания  
Дата: 03.10.22 16:58
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

S>·>Не очень понял что этот процент значит в контексте CAP.

S>В контексте CAP — ничего не значит. Именно поэтому она полезна примерно никак. Инженеры не измеряют доступность в терминах "есть/нету". Доступность в reliability engineering — это доля успешно обслуженных запросов.
Это терминологическая придирка. Да, один термин означает разные вещи в разных контекстах... ну бывает.

S>·>Если сценарий — деньги списались, но не удалось в течение 15 минут завершить резервацию, сервер упал, то извиняемся перед клиентом и возвращаем деньги. Проблема в том, что деньги будут возвращены только после 15 минут+время на восстановление упавшего сервера и успешной отправки инструкции отмены списания денег. И это нарушение availability, т.к. у клиента будет минус на счету и ему может не хватить денег на покупку нового билета.

S>·>Если сценарий — деньги списались, резервирование завершилось, но клиент про это не смог узнать (т.к. всё легло) и пропустил рейс, то тоже проблема. Нарушение consistency.
S>А если сценарий — деньги списались один раз, но резервирований произошло два (или N) — это нарушение чего? Без идемпотентности вы не сможете достичь даже at most once.
Нарушение консистентности же.

S>·>А какие варианты-то?

S>Варианты — постараться автоматически вернуть согласованность после окончания partition.
Так ведь окончание может наступить слишком поздно, т.е. нарушение availiability.

S>>>Ну, так мы и вернулись к вопросу идемпотентности. Прокси-то ответит не то, что стало с ресурсом теперь, когда его потрогали другие клиенты. Он вернёт из кэша ровно тот же 200 Ok, что сервер отдал ещё при первой попытке.

S>·>Запросом клиента будет "деньги списались, резервирование завершилось?" — ответ будет OK хоть год спустя. Или я не понял которую операцию ты имеешь в виду. В твоём сценарии будет несколько операций.
S>Чтобы это было "ок хоть год спустя", как раз и нужна идемпотентность. Иначе получается так, что прокси бы ответил "200 Ok", а сервер при вопросе напрямую — "409 conflict", потому что бронирование перестало быть актуальным.
Мы видимо в голове разные сценарии и набор операций себе представляем. Я не очень понимаю возражение.

S>·>Согласен, идемпотентность нужна для обеспечения консистентности. Но мы, вроде, говорим о сценарии, который состоит из множества операций. Идемпотентность каждой из операции никакой магии не сделает и CAP обойти не сможет.

S>Нам не нужно обходить CAP. Нам нужно максимизировать A и C.
Т.е. значит нам придётся минимизировать Partitioning. Всё в соответствии с теоремой.

S>>>после окончания partition.

S>·>Т.е. при отсутствии Partition мы можем наконец-то получить Consistency и Availabilty. Ну да, всё в соответствии с теоремой.
S>При отcутствии "сильной идемпотентности" у нас Consistency и Availability не достигаются даже после окончания Partition.
Я честно говоря, не понял что такое "сильная" и чем отличается от "слабой". Как по мне, обычной идемпотентности f*f=f хватит. Про другие не знаю.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[45]: Идемпотентность POST - хорошая ли практика?
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.10.22 17:33
Оценка:
Здравствуйте, ·, Вы писали:
S>>В контексте CAP — ничего не значит. Именно поэтому она полезна примерно никак. Инженеры не измеряют доступность в терминах "есть/нету". Доступность в reliability engineering — это доля успешно обслуженных запросов.
·>Это терминологическая придирка. Да, один термин означает разные вещи в разных контекстах... ну бывает.
Нас интересует тот термин, у которого есть практическая полезность.
CAP-теорема делает вид, что существует всего два класса распределённых систем — C- и A- системы.
Это, мягко говоря, неправда. Есть целый спектр систем между двумя полюсами; для некоторых задач мы вообще можем двигать ручку между A и С вправо-влево.
А для некоторых задач внезапно выясняется, что и при сохранении строгой согласованности можно добиваться близкой к 100% доступности даже при крайне низкой надёжности сети между узлами.

S>>·>А какие варианты-то?

S>>Варианты — постараться автоматически вернуть согласованность после окончания partition.
·>Так ведь окончание может наступить слишком поздно, т.е. нарушение availiability.
А может и не наступить. Вот мы и приходим к статистическим параметрам вместо банальной "тут нет гарантии availability".
Системы, которые восстанавливают consistency автоматически после восстановления связи, предпочтительнее тех, что требуют ручного вмешательства.
Хотя бы потому, что их итоговая availability оказывается выше. Не имея идемпотентных "кирпичиков" мы вынуждены полагаться на способность пользователя и админов успеть починить повреждённые данные за 15 минут, даже если сетка моргнула на 1 минуту в самом начале или VM была перезагружена. А если у нас такие кирпичики есть, то всё, что заметит пользователь — некоторую задержку в обработке его заказа.

·>Мы видимо в голове разные сценарии и набор операций себе представляем. Я не очень понимаю возражение.

Я в начале ветки привёл подробный пример того, чем "сильная" идемпотентность отличается от "слабой".

·>Т.е. значит нам придётся минимизировать Partitioning. Всё в соответствии с теоремой.

Нет, partitioning нам задан свыше, как свойство среды. Можем её определить количественно, как параметры распределения для расписания сбоев.

S>>При отcутствии "сильной идемпотентности" у нас Consistency и Availability не достигаются даже после окончания Partition.

·>Я честно говоря, не понял что такое "сильная" и чем отличается от "слабой". Как по мне, обычной идемпотентности f*f=f хватит. Про другие не знаю.
Вот тут описано, чем отличается сильная от слабой: https://rsdn.org/forum/design/8374428.1
Автор: Sinclair
Дата: 01.10.22

При слабой идемпотентности повторная попытка A создать X в момент времени между 2 и 3 вернёт ему ошибку 4хх (или 200 ok с затиранием X'), а в момент времени после 3 создаст ещё один экземпляр X. В итоге мы получим рассогласование.
При сильной идемпотентности повторные попытки A cоздать X всегда будут отдавать ему 201, независимо от момента повтора; при этом восстановления X не произойдёт — в точности так же, как если бы A общался через прокси, который "запомнил" ответ 201, отданный сервером на самую первую попытку создания, и всегда отвечал именно его, не консультируясь с сервером.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[30]: Идемпотентность POST - хорошая ли практика?
От: maxkar  
Дата: 04.10.22 10:25
Оценка: 5 (1) +1
Здравствуйте, Sinclair, Вы писали:
S>Очень, очень верное замечание.
S>Есть ли ссылки на готовые материалы почитать по данной теме?
S>Я не припомню, чтобы я встречал где-то рассуждения о слабой/сильной идемпотентностях; хотя, очевидно, желанной является вторая.
Обсуждений в чистом виде про семантику идемпотентности (и её возможных трактовок) я тоже не встречал. Часть практических вопросов, наверное, можно найти в системах сообщений, обеспечивающих как минимум одну доставку (at-least-once). Часто там еще бывает переупорядочивание (либо в силу самой системы, либо из-за того, что гарантированная отправка исходного сообщения может задействовать повторы), поэтому практические подходы умеют все это учитывать. Если интересует (математическая) теория, есть связная область, изучающая Conflict-Free Replicated Data Types (CRDT). В качестве вводных материалов можно посмотреть на https://crdt.tech/. Идеи REST очень хорошо соотносятся с State-Based CRDT (можете в Glossary посмотреть). Там как раз идет передача полного состояния (здравствуй, PUT). Функция слияния состояний (merge) включает в себя требования идемпотентности. Может быть, где-то в теоретических работах (не только по state-based) есть и новые названия для различных классов гарантий. На практике и другие CRDT могут быть полезны. Например, operation-based можно моделировать через "одноразовый" (at most once) PUT /entity/<id>/operations/<uniqueId>. PUT может только создать новый ресурс, либо вернуть 409/200 (конфликт или повтор). Или есть Delta-Based, которая может быть похожа на (сильно-)идемпотентный PATCH.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.