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

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

Hey Ben,

Thanks for the thoughts. We're all just a bunch of programmer's trying to make 
Thrift better and your voice is as important as everyone else's.

Regarding default values I have a different view. You suggest that the best 
case would be to eliminate default values. I think that could be fine guidance 
in some environments but not Thrift. 

*default values are a key interface evolution feature*

In a world of continuous integration and continuous delivery, where large scale 
distributed applications have many tenants, changing an interface can be a very 
hard thing to do. I have built some fairly large systems using IDLs with no 
provisions for interface evolution and the lack thereof cost my team in many 
ways on many occasions. I began using Apache Thrift for its interface evolution 
features as much as for its cross language features.

Default values are a key enabler of Apache Thrift's interface evolution 
capability. If I have this interface today:

struct data {
     1: i32 x
}

But need to improve my servers' feature set by adding support for the passing 
of y, for which a reasonable default value is 5, I can modify my interface in 
the following way:

struct data {
     1: i32 x
     2: i32 y = 5
}

Now my new server can handle calls from new clients passing y as they come 
online. Yet when an old client calls and does not pass y, the default stands in 
and all is well. As an interface evolution feature defaults are critical. Keep 
in mind that y here is not optional, it has normal requiredness, which in 
Thrift means, serialize it if you have it when writing but don't expect it to 
always be there when you are reading. There's no isset bit to test to see if 
the value was sent or not. Without a default value you have a quandary.

As a case study, consider protocol buffers. Google Protobufs have only optional 
and required fields. Optionals can have a default value and if they are not 
found when reading they are set to their IDL default. If there is no IDL 
default they are set to their type default (0 for scalars, for example). This 
is another case of the reader using a default value when a field is not found 
in the stream and bears the same evolution value as presented above for Thrift. 
A number of other platforms have also felt the need to create this evolutionary 
escape hatch using defaults.

There is no getting around it, if you change the default value in an interface 
you leave yourself open to some edge cases which are subtle and could be quite 
vexing. However, I believe that eliminating default values would be throwing 
the baby out with the bath water. 

_So I contend that default values have great utility but carry cautions that 
must be observed, and that this is an issue independent of the optimization we 
are discussing_

*Optional is an optimization*

Note that in the Thrift example above, normal requiredness was in use, it and 
default values are the work horses of interface evolution. In Thrift optional 
is not an interface evolution feature. It is an optimization. It allows me to 
avoid serializing something if I do not need to. I don't think anyone is 
arguing with the utility of optional in general.

The proposal here is to extend that optimization such that, those who choose 
to, can avoid serializing default values. Given that we have optional 
requiredness and default values already, this seems like a reasonable semantic 
for the pair. It is also popular, Facebook has already implemented it and 
numerous folks have asked for it. I don't personally have a use case but I can 
certainly see the motivation.

Adding this semantic in no way obligates anyone to use the feature and every 
other possibility is still in play. Presently optional requiredness and default 
values are poorly defined, confusing and somewhat haphazardly implemented. I 
see this proposal as a step in the right direction, creating clear semantics 
around all combinations of IDL features. Certainly a step in the right 
direction for usability.

As a foot note this feature does not touch the Thrift Protocols. It is at the 
Type engine level. IDL Compiler generated type code is the correct level of 
abstraction to test the default values before serializing. 
Binary/Compact/etc... would be oblivious to this feature and go on unchanged 
(essentially as implemented by Facebook). 

Interested to hear counterpoints and what other think here. 

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