[ 
https://issues.apache.org/jira/browse/THRIFT-2429?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13967431#comment-13967431
 ] 

Randy Abernethy commented on THRIFT-2429:
-----------------------------------------

Hi Ben, 

I agree that required should be used with care and that thrift required and pb 
required are the same semantic. What I think may be falling through the cracks 
is that PB has two settings to determine whether something is serialized, 
"optional" & "required" but Apache Thrift has three, "optional", *normal* and 
"required". Normal is the basic tool for interface evolution. Optional extends 
the evolution features with the ability to optimize away fields that need not 
be serialized.

For example, consider the following IDL: 

{code:title=x.thrift|borderStyle=solid}
struct Trade {
    1: required string       fish    //required requiredness
    2:          double       price   //normal requiredness
    3: optional i32          size    //optional requiredness
}
{code}

Note that price is not "optional" and it is not "required", it is "normal" a 
third independent case.

Now imagine a client passes a Trade to a server with only "fish" set because it 
has this old IDL:

{code:title=y.thrift|borderStyle=solid}
struct Trade {
    1: required string       fish    //required requiredness
}
{code}

This will _not_ cause an exception. Neither "normal" (price), nor "optional" 
(size) need be present in the stream when read. Only the "required" field is 
required by the reader. Thus you can delete the "normal" price field and have 
compatibility.

Now go the other way, imagine a client that knows the first IDL sends a Trade 
with all three fields to a server that knows the second IDL. The server will 
ignore the fields it does not recognize (price & size). Thus "normal" fields 
can be added without breaking compatibility. They are not "required", they are 
not "optional", they are "normal". They work like regular struct properties, 
without the need for set/unset and testing for presence on the server, which 
makes them straight forward to use, but they support interface evolution. 

So what is the distinction between normal and optional? The difference is that 
while both "size" and "price" are allowed to be absent on the deserializing 
size, only "size" can be omitted on the serializing side. In other words, 
serializers that know about the (normal) "price" field will always serialize 
it. On the other hand the (optional) "size" field can be sent or not sent at 
the discretion of the client. The client can optimize away "size" when it is 
not needed.

So:
* required - has no evolution capability (as Jens says, you can't remove or add 
these)
* normal - provides interface evolution support (you can safely add and delete 
these)
* optional - provides interface evolution support and adds the ability to 
optimize away the field during serialization 

If you want to build a normal struct that is sent to a server but make sure 
that you can evolve the interface down the road, "normal" requiredness works 
great. It clearly communicates your intent (send the whole thing) and lets you 
use the struct naturally (without set/unset/isset/testing on the server, etc.).

If you want to create a struct with 50 fields of which only two or three are 
set at a time, optional is the way to go. Optional does not buy you any 
additional interface evolution features, it lets you selectively serialize the 
fields required.

You make a great point, in that we do not have decent docs on this stuff. One 
of the requirements for this ticket!

Best,
Randy


> Provide option to not write default values, rely on receiver default 
> construction instead
> -----------------------------------------------------------------------------------------
>
>                 Key: THRIFT-2429
>                 URL: https://issues.apache.org/jira/browse/THRIFT-2429
>             Project: Thrift
>          Issue Type: Improvement
>          Components: C++ - Compiler
>    Affects Versions: 0.9.1
>            Reporter: Chris Stylianou
>            Assignee: Randy Abernethy
>              Labels: default, optional, required
>
> Would there be any objections to a patch that does not write default values 
> (essentially the same logic as the optional attributes). This obviously 
> relies on the receiving application using the same IDL version to ensure the 
> defaults used on object construction match the senders.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

Reply via email to