[
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)