Re: CORBA IDL versioning, evolution, backward compatibility
- From: "Mark Woyna" <woyna@xxxxxxxxxxx>
- Date: 15 Sep 2005 07:46:50 -0700
Michi Henning wrote:
>Mark Woyna wrote:
>
>> Solution: Extend existing interfaces with new interfaces, and add
>> the new operations to the derived interface. New clients will use the
>> new interfaces, thus picking up the new operations. Older clients will
>> continue to work with the older interface.
>
>> interface MyServiceV2 : MyService {
>> // new operations
>> };
>
>This is not really a solution. For one, you quickly end up with
>a dog's breakfast of an inheritance graph that is incomprehensible
>to mere mortals. Second, real-life versioning requirements are not
>that well-behaved. Real applications need to do things such as
>adding a field to struct, changing the signature of an operation,
>adding or removing a parameter of an operation, etc. And, quite
>often, the versioning requires a change in *behavior* of an operation,
>but not its signature. None of these can be achieved with versioning
>by derivation.
Yes, it can get messy, but we've been using it successfully for 5+
years in a *real* application. Adding a new operation (i.e. an existing
operation with additional parameters) is the cleanest. As you point
out, modifying a struct can have nasty cascading affects. First, since
you have to create a new struct, all existing operations that use the
old struct will have to be duplicated in the new interface. Blech. If
there's an existing inheritance relationship, it gets worse.
In addition, the internal implementation must now deal with the problem
of converting the old operation implementation into calls to the new
implementation. In some cases this is easy, as one simply creates the
new structs internally, provides default or "null" values for the new
fields, and calls the new operation. In other cases, there may be no
clean mapping to the new implementation, e.g. the new parameter does
not have a valid default value.
>
>> Note: Depending on the orb, you may be able to add additional
>> operations to the bottom of an interface, which results in less clutter
>> due to the elimination of the need for new interfaces. However, this is
>> generally non-interoperable, as all client orbs in your system must
>> support this capability. Existing client stubs will continue to work,
>> as they'll be oblivious to the new operations.
>
>This works, but only by accident, and only for the remote case. If you
>collocate a V1 client with a V2 version of that interface, things are
>likely to blow up. It will also cause grief if you want to use the IFR
>and DII to do dynamic dispatch.
Yes, it is completely dependent on how the orb maps operation names to
the underlying implementation. As long as we add operations to the
bottom of the interface, our orb works fine. Of course, this works best
in an environment using a single orb, or one where you can dictate the
choice of orbs. We limit this approach to our internal interfaces, and
use an adapter tier with our external clients. The adapter tier is much
more restrictive.
>
>> We've had decent luck with using an adapter tier, which shields the
>> clients from the server-side services. This allows us to internally
>> evolve our business services without having to expose every minor
>> change to the client. For major releases incorporating new client
>> functionality, we produce a new version of our public IDL. The adapter
>> tier exposes all versions of the interfaces, including those going back
>> to version 1. Unfortunately, we don't have complete control to force
>> users to migrate to the new interfaces. However, there's usually enough
>> value in the new features to encourage our clients to migrate at some
>> point, e.g. additional data carried in the callback methods.
>
>A lot of work, unfortunately.
Well, we were going to need the adapter tier for other good reasons
anyway. Luckily, we didn't have to create it to deal with the
versioning issue exclusively. The additional tier allows us much more
flexibility in modifying our internal business service interfaces,
without exposing ever minor change out to our external clients. In
essence, the adapter tier is a basic facade pattern. New features that
require API changes are typically bunched together, so we can issue a
major release of the API, rather than a continuous flow of modified
IDL.
> One quite effective approach is to make
>clients trade for the version they need. In effect, you add a small
>bootstrap interface to your application that clients use to get
>the initial few objects they need:
>
>interface Bootstrap {
> Object getObject(in string name, in string wantedVersion,
> out string supportedVersion);
>
>};
Yes, this is basically what the adapter tier provides. Each release
provides a new "bootstrap" interface (UserSessionManager), which the
client uses to access the other versioned interfaces. We wanted to
avoid introducing a trader or name service between us and our external
clients, so the interface serves as basic finder service.
>
>Add exceptions as you see fit. The idea is that the client asks for
>a version of an object, and the server returns that version or a
>compatible version, together with what version the returned object
>actually supports. The client then can use a mixture of V1 and V2
>objects and types as appropriate.
Yup, that's it in a nutshell.
>
>This isn't a panacea, but it can work. One of the more annoying
>aspects is that changes in behavior only still require creating
>a new interface type, even though the signatures are all the same.
I would say that we try to avoid changing the behavior of an operation,
as this can create all types of headaches. As you point out, it's best
to simply define a new operation, and deprecate the old operation (if
possible) at some point in the future.
>
>Another option is to (ab)use the IDL context to send the version
>that a client is using. This allows the server to modify its
>behavior accordingly and change the behavior of operations as needed.
>But that approach also isn't all that pretty, and prone to errors
>because there is no type checking of the IDL context of any kind,
>and because the context pollutes the APIs.
Yes, we considered that at one point, but rejected it more or less for
the reasons you stated.
>
>What CORBA needs is some form of multiple interfaces. Back in
>about 1997, when there was an RFP for this feature, people
>unfortunately argued that there is no need for multiple interfaces
>because derivation is all that is necessary. As you found out,
>that argument is flawed because real-world applications stubbornly
>refuse to listen to academics...
As Doug points out, Facets might do the trick. However, our orb doesn't
support them at this time, but it's something we'll have to seriously
consider before we hit version 13 of our interfaces. :-)
As to the deficiencies of CORBA w.r.t. versioning, I'd still amazed
that it doesn't support basic polymorphism! If I create a derived
interface, and provide an implementation of that interface that also
inherits from the base interface/implementation, I can't simply export
the reference to the new interface and expect old clients to be able to
use the new reference (as the old type)! I have to create two
references for the two types, and export them both. Ugh.
Another thing I would like to see is versioned structs without
requiring all the baggage of valuetypes. As we bemoaned above, one
can't add a new field to an existing struct, and creating a new struct
has a massive rippling affect on the existing interfaces. It would
grand to be able to pass a new derived struct to an existing method,
and have it work as an instance of the base type.
We've discussed adding proprietary features into our orb to support
versioning (for internal services), but we've been very reluctant to go
there, as we'd like to stick to the standards.
I looked at ICE, but it doesn't appear that there's any support for
these aspects of versioning as far as I'm aware. Do you have any plans
to support versioned interfaces and structs? The ICE protocol didn't
seem to carry any versioning information.
Mark
>
>Cheers,
>
>Michi.
>
.
- Follow-Ups:
- Re: CORBA IDL versioning, evolution, backward compatibility
- From: Michi Henning
- Re: CORBA IDL versioning, evolution, backward compatibility
- References:
- CORBA IDL versioning, evolution, backward compatibility
- From: Malcolm McRoberts
- Re: CORBA IDL versioning, evolution, backward compatibility
- From: Mark Woyna
- Re: CORBA IDL versioning, evolution, backward compatibility
- From: Michi Henning
- CORBA IDL versioning, evolution, backward compatibility
- Prev by Date: Re: DOM Interoperability with CORBA
- Next by Date: Re: IDL design
- Previous by thread: Re: CORBA IDL versioning, evolution, backward compatibility
- Next by thread: Re: CORBA IDL versioning, evolution, backward compatibility
- Index(es):
Relevant Pages
|