PATCH处理器有一些有趣的行为。从评论中:
// first time through,
// 1. apply the patch
// 2. save the original and patched to detect whether there were conflicting changes on retries
// on a conflict (which is the only reason to have more than one attempt),
// 1. build a strategic merge patch from originalJS and the patchedJS. Different patch types can
// be specified, but a strategic merge patch should be expressive enough handle them. Build the
// patch with this type to handle those cases.
// 2. build a strategic merge patch from originalJS and the currentJS
// 3. ensure no conflicts between the two patches
// 4. apply the #1 patch to the currentJS object
我认为有三种可能对patch产生意义的操作模式:
- 用户指定RV;patch尝试一次。如果RV不再匹配,则失败(如果用户的补丁以不可预测的方式依赖于对象的某些部分,这是有意义的)。
- 用户不指定RV;patch尝试多次,如果补丁停止干净地应用,则失败(用户选择放弃任何锁定--'.spec.replicas'应该是X,我不关心其他人说什么)。
- 用户指定一个基本对象和一个补丁;补丁将补丁更改解释为对每个更改具有隐含的“from”前提条件。只要具有隐含前提条件的补丁继续干净地应用,就一直重试。(用户希望并发安全地应用,并希望服务器执行重试循环。而且补丁是可预测的。)
不幸的是,今天的代码没有做上述任何合理的事情,而是将2和3混淆在一起。编辑:1和2已经在#63146中得到解决。
如果用户尝试今天的情况1,我们认为它仍然会进行5次重试,即使如果第一次有一个冲突,那么其他几次也一定会有冲突。
如果今天的用户没有指定RV,今天的重试循环会进行一些无意义的冲突检测:用户没有指定与RV的关系,因此在请求首次进入时使用RV作为“基本对象”是一个任意的选择。如果生成冲突,用户只是会用完全相同的补丁重试。
如果用户想要行为3,今天没有办法实现它。我个人记得行为3是PATCH最初宣传的行为,但这似乎不是普遍的记忆。
所以,我提议进行以下更改: - 如果用户在补丁中指定了RV,不要进行任何重试。这是向后兼容的,因为他们本来都会失败。已在collapse patch conflict retry onto GuaranteedUpdate #63146中完成。
- 如果用户没有指定RV,不要进行评论中提到的冲突检测,只需使用原始补丁重试。我认为这是向后兼容的,因为所有导致失败的原因实际上都是无意义的。已在collapse patch conflict retry onto GuaranteedUpdate #63146中完成。
- 为用户提供一种有意调用行为3的方法。这将是一项“新”功能。
8条答案
按热度按时间lyr7nygr1#
感兴趣的人:@liggitt@wojtek-t@bgrant0607@apelisse
gcuhipw92#
@lavalamp ,我有一个问题:
"用户如何在补丁中指定RV"
作为请求的一部分,您只指定了"应该应用的补丁"。并没有真正说明初始对象的样子(以及它所在的版本)。所以我不确定这是否可能。
[我同意,如果这是可能的,那么在这里不重试是有意义的]
0qx6xfy63#
用户如何在补丁中指定RV?
例如:
{"metadata":{"resourceVersion":"10"},"foo":"bar"}
/assign
lpwwtiir4#
等等,这意味着我们想覆盖RV到10,对吗?
laik7k3q5#
that takes whatever the object coming from etcd is, sets resourceVersion=10, and foo=bar, then tries to store it. that lets you set the resourceVersion=10 precondition, which gives you normal resourceVersion semantics when it tries to persist
h6my8fg26#
好的,我忘记了那个rv=10的对象实际上是对那个版本的一个先决条件。
谢谢你的解释。
u5rb5r597#
问题在90天不活跃后过期。
使用
/remove-lifecycle stale
将问题标记为新鲜。过期的问题在30天不活跃后开始腐烂并最终关闭。
如果现在可以安全地关闭此问题,请使用
/close
进行操作。向 sig-testing, kubernetes/test-infra 和/或 fejta 发送反馈。
生命周期:过期
xpcnnkqh8#
/remove-lifecycle stale