<p dir="ltr">Dmitry,</p>
<p dir="ltr">Feature strings won't work. It only makes things more complex, without addressing the underlying issue.</p>
<p dir="ltr">What happens when we change, even in a small way, the API surface exposed by an existing feature? How is that change exposed -- unless we include a version number along with your feature string? And now we're right back where we started.</p>
<p dir="ltr">-Deva<br>
 </p>
<br><div class="gmail_quote"><div dir="ltr">On Fri, Jun 26, 2015, 07:41 Dmitry Tantsur <<a href="mailto:dtantsur@redhat.com">dtantsur@redhat.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 06/26/2015 04:08 PM, Sean Dague wrote:<br>
> On 06/26/2015 07:43 AM, Dmitry Tantsur wrote:<br>
>> On 06/26/2015 01:14 PM, Sean Dague wrote:<br>
>>> On 06/16/2015 09:51 AM, Dmitry Tantsur wrote:<br>
>>>> On 06/16/2015 08:56 AM, Dmitry Tantsur wrote:<br>
>>>>> To sum this long post up, I'm seeing that hiding new features based on<br>
>>>>> microversions brings much more problems, than it solves (I'm not aware<br>
>>>>> of the latter at all). I'm very opposed to continuing doing it in<br>
>>>>> Ironic, and I'm going to propose patch stopping gating Kilo changes<br>
>>>>> (non-breaking obviously).<br>
>>>><br>
>>>> I'm talking about this patch: <a href="https://review.openstack.org/#/c/192196/" rel="noreferrer" target="_blank">https://review.openstack.org/#/c/192196/</a><br>
>>>> We have to do it right now, as otherwise we can't test inspection in<br>
>>>> tempest (it does not seem to be microversion-aware).<br>
>>><br>
>>> Dmitry,<br>
>>><br>
>>> How do you solve for the following situation?<br>
>>><br>
>>> 2 Clouds (A and B), both being Continuously Deployed.<br>
>>><br>
>>> Assume both clouds start at same revision of code. At point in time T a<br>
>>> new "compatable change" is added to the API. For instance, another field<br>
>>> returned by some resource.<br>
>>><br>
>>> Cloud B upgrades to that change.<br>
>>><br>
>>> Brand new developer shows up. Starts writing application against Cloud<br>
>>> B. Sees that change is available at version 1.4. Hard codes her<br>
>>> application to use this parameter.<br>
>>><br>
>>> Then she points her application at Cloud A. And it explodes.<br>
>><br>
>> I clearly agree that my solutions do not solve this situation. Neither<br>
>> does yours. Now let us see:<br>
>><br>
>> A compatible change is getting added and is guarded behind version 1.5.<br>
>> A new developer starts requiring this new version, because she needs<br>
>> this new feature (that's your assumption).<br>
>><br>
>> Then she points her application at cloud A. And it explodes. But with<br>
>> different error message and probably a bit earlier. But explodes.<br>
>><br>
>> Which, by the way, means we still must know precisely which API version<br>
>> is served by all clouds we might apply our utility to.<br>
><br>
> But it fails with "Your application is attempting to use API 1.5 which<br>
> is not supported in this cloud". Because if you don't specify a version,<br>
> you get the base 1.0, and never had new features.<br>
><br>
> That's an error which is extremely clear to understand what went wrong.<br>
> Has docs to figure out if the application could work at an earlier<br>
> release version, and provides the ability for the client to do some<br>
> selection logic based on supported versions.<br>
<br>
I agree that error is clear. I'm not sure it's worth doing despite all<br>
the problems that I mentioned in the beginning of this thread. In<br>
particular, situation around official CLI and testing.<br>
<br>
E.g. do you agree with Jim that we should make API version a required<br>
argument for both CLI and Python library?<br>
<br>
><br>
>       -Sean<br>
><br>
>><br>
>> So I agree, hitting API version error could make a person realize that a<br>
>> change to the utility is no longer compatible with the current version<br>
>> of API. So if this change wasn't intended - fine. If it was (which is<br>
>> the most likely situation), it won't help you.<br>
>><br>
>> By the way, I've heard some people wanting to deprecate API version with<br>
>> time. If we do so, it will open some new horizons for breakages.<br>
>> If we don't, we'll soon end put with dozens of version to support and<br>
>> test. How to solve it? (in Ironic IIRC we just only gate test one<br>
>> version, namely Kilo aka 1.6, which is very, very bad IMO).<br>
>><br>
>>><br>
>>><br>
>>> I feel like in your concerns there has been an assumption that the<br>
>>> operation across all clouds effectively always goes forwards. But<br>
>>> because we're trying to encourage and create a multicloud ecosystem a<br>
>>> user application might experience the world the following way.<br>
>>><br>
>>> Cloud A -> Cloud A' -> Cloud A'' -> Cloud D -> Cloud B' -> Cloud C -><br>
>>> Cloud C'.<br>
>><br>
>> I think that versioning actually encourages this (wrong) assumption.<br>
>> Because versions grow with time naturally, and we, the developers, like<br>
>> new and shiny stuff so much :) see below for my alternative idea.<br>
>><br>
>>><br>
>>> While no individual cloud is likely to downgrade code (though we can't<br>
>>> fully rule that out), the fact that we'd like applications to work<br>
>>> against a wide range of deployments means effectively applications are<br>
>>> going to experience the world as if the code bases both upgrade and<br>
>>> downgrade over time.<br>
>>><br>
>>> Which means that a change is only "compatable" if the inverse of the<br>
>>> change is also "compatable". So a field add is only compatable if the<br>
>>> field delete is also considered compatible, because people are going to<br>
>>> experience that when they hop to another cloud.<br>
>>><br>
>>> Which is also why feature hiding is a thing. Because we don't control<br>
>>> when every cloud is going to upgrade, and what they'll upgrade to. So<br>
>>> the best idea so far about getting this right is that API 1.4 is<br>
>>> *exactly* a specific surface. Features added in 1.5 are not visibile if<br>
>>> you ask for 1.4. Because if they were, and you now wrote applications<br>
>>> that used that bleed through, when you jump to a cloud without 1.5 yet<br>
>>> deployed, all your application code breaks.<br>
>><br>
>> Note that if you rely on version 1.4 with feature hiding, your<br>
>> application will also break. I.e. I agree it's a valid situation to fix,<br>
>> I just don't see feature hiding fixing *all* cases of this problem.<br>
>> While an API exposing feature explicitly might be more handy, imagine e.g.<br>
>><br>
>> $ curl <a href="http://ironic.host/v1/features" rel="noreferrer" target="_blank">http://ironic.host/v1/features</a><br>
>> ['inspection', 'raid', ...]<br>
>><br>
>> Exposing interface like that would encourage people to think about their<br>
>> application in terms of mandatory and optional features, not some numbers.<br>
><br>
> Yes, version number is being used as a proxy for a feature description.<br>
> Which is what version numbers are used for in software. It's a way to<br>
> let people think about bundles of things, instead of having to mentally<br>
> map out every single feature in their head.<br>
<br>
Why do you think it's good? People are using features, not numbers. They<br>
don't need to map out features - on the contrary they do need to map<br>
versions to features. We've reached 1.8 with Ironic - and I (the core)<br>
don't remember what were these version about, except for 1.6.<br>
<br>
><br>
> Maybe we can some day to a place where we can have an API that's fully<br>
> feature describing, and doesn't need numbers. But after 2.5 years of<br>
> trying to do a major rewrite of the Nova API, it was pretty clear that<br>
> APIs of any reasonable size just can't do that. And can't rely on<br>
> software to keep up with your changes. This provides a mechanism for<br>
> evolution with a stability contract that API 1.4 is going to keep<br>
> looking exactly the same over time. So you can upgrade client code on<br>
> your schedule, not on the schedule of the server upgrades.<br>
<br>
I don't see any problem with creating an API serving list of strings,<br>
and then making contributors update this list every time they change<br>
API. It's the same as making contributors bump version number.<br>
<br>
><br>
>       -Sean<br>
><br>
<br>
<br>
__________________________________________________________________________<br>
OpenStack Development Mailing List (not for usage questions)<br>
Unsubscribe: <a href="http://OpenStack-dev-request@lists.openstack.org?subject:unsubscribe" rel="noreferrer" target="_blank">OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a><br>
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" rel="noreferrer" target="_blank">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br>
</blockquote></div>