如何使必需的节俭字段可选?

时间:2016-06-01 02:03:53

标签: thrift

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

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

...但我希望content可选。

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

2 个答案:

答案 0 :(得分:8)

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

  

必须永远

     

您应该非常小心地根据需要标记字段。如果您希望在某个时刻停止写入或发送必填字段   将字段更改为可选字段(旧字段)会有问题   读者会认为没有这个字段的消息是不完整的   可能会无意中拒绝或放弃它们。你应该考虑写作   缓冲区的特定于应用程序的自定义验证例程   代替。有些人得出的结论是,使用必需品更多   弊大于利;他们更喜欢只选择使用。但是,这种观点   不是普遍的。

我担心唯一的选择是弃用整个结构并创建一个新结构。

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

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

如果未指定requiredoptional,则会隐式应用“默认”要求。

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

答案 1 :(得分:2)

如果您通过以下步骤控制结构的所有读取器和写入器,则可以执行此操作:

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