【问题标题】:How do I make a required thrift field optional?如何将必需的节俭字段设为可选?
【发布时间】:2016-09-30 05:02:28
【问题描述】:

在节俭中制作required 字段optional 的最佳过程是什么。例如,我有一个结构......

struct Message {
    1: required double userID;
    2: required string content;
    ...
} 

...但我想将content 设为可选。

编辑:澄清一下,我已经有使用这个结构的消费者,所以我需要在不破坏这些消费者的情况下更新它。分阶段升级很好(即 ​​- 添加新的 optional 字段,更新下游客户端,然后删除 - 或停止使用 - 旧的 required 字段)。

【问题讨论】:

    标签: thrift


    【解决方案1】:

    你不能,因为俗话说需要就是永远。以下是 Diwaker Gupta 强烈推荐的 "Missing Guide" 的引述。它几乎确定了为什么在使用required 之前应该三思(至少):

    需要是永远的

    您应该非常小心地根据需要标记字段。如果在某些时候您希望停止编写或发送必填字段,它 将字段更改为可选字段会出现问题 — old 读者会认为没有此字段的消息不完整,并且 可能会无意中拒绝或丢弃它们。你应该考虑写 缓冲区的特定于应用程序的自定义验证例程 反而。有些人得出的结论是,使用 required 做得更多 弊大于利;他们更喜欢只使用可选的。然而,这种观点 不是通用的。

    恐怕唯一的选择是弃用整个结构并创建一个新结构。

    除此之外,实际上有三个必要度,其中只有两个有关键字:

    • required: 读时必须存在,写时必须设置
    • optional: 可以设置也可以不设置,完全可选
    • “default”:读取时可能不存在,总是写入(除非是null指针)

    requiredoptional 均未指定时,将隐式应用“默认”要求。

    正如我们所看到的,如果我们查看事物的兼容性站点,required 的限制是相当严格的。即使向结构添加新的required 字段也可能导致不兼容,例如如果新客户端正在从旧服务器读取数据(反之亦然),因为新的required 字段不在旧实现写入的数据中,而是新实现所期望的。

    【讨论】:

    • 这句话是针对“读者”的,但是对于老的作家呢?如果只有一个阅读器并且它将合同更改为可选,但遗留作者仍在按要求编写它,这会破坏吗?
    • "如果只有一个阅读器,并且它将合同更改为可选,但旧版编写器仍在按要求编写它,这会中断吗?" -- 不,那个特定的星座应该可以工作。修改已发布的 API 是违反推荐做法的,但是是的,这应该可行。
    【解决方案2】:

    如果您通过以下步骤控制结构的所有读取器和写入器,则可以做到这一点:

    1. 将 thrift 架构中的字段从必需更改为可选。在引用或使用此结构的所有系统中同步此新模式。不要停止写入此字段。这是一个安全的更改,因为该字段仍将始终存在。
    2. 只有在使用此结构的所有系统中部署架构更改后,您才能在某些情况下停止写入此字段。现在这样做是安全的,因为此字段在每个系统中都被标记为可选,没有其他答案中提到的“老读者”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-15
      • 1970-01-01
      • 2015-02-26
      • 2019-06-07
      • 1970-01-01
      • 2019-08-18
      • 2015-11-13
      相关资源
      最近更新 更多