Subject: Re: improving ABI "survival rate"

Re: improving ABI "survival rate"

From: Daniel Stenberg <daniel_at_haxx.se>
Date: Fri, 28 Nov 2008 08:09:42 +0100 (CET)

On Fri, 28 Nov 2008, Yang Tse wrote:

> The introduction of a new public function somehow breaks API and ABI.
> 'People' are fond of saying that there is no need to make a SO bump when
> this is done. But actually it should be done. A program which counts on the
> existence of the new function will fail when faced with a shared library
> with the same SO number but which actually is a previous binary version in
> which the new function didn't exist yet. I won't argue this further, I just
> wanted to mention my personal opinion on what I think is a wrong-doing but
> quite common practice.

I know and I agree with this general sentiment. But in my mind the ABI is more
important to maintain with existing apps that were compiled before the new
function was even invented, than for applications that are built when the new
function exists and then are ran with an older lib using the same major soname
number but without that new function.

There's also the fact that the "community" seems to have this view of things
and keeping the major soname number when adding function are generally
accepted and consider the right thing so if we bump it for this, we'll get a
lot of people lecturing us and whining on "unnecessary" bumping. Heck even
more clearly required soname bumps can be hard to get people to accept
sometimes due to peoples extreme antipathy for them.

> Now, let's imagine that someone has used ares_setopt() to setup a couple of
> IPv6 nameservers. This information cannot be stored in a variable of the
> existing ares_options struct, so somehow it will be kept 'somewhere' before
> doing some sort of, some other new public functions,
> ares_init_channel_with_newstyle_opts(), and even
> ares_destroy_newstyle_opts().

Right, the exact storage struct would be internal to c-ares then and there
would be no new struct for this exposed to apps.

> Now the user, or the library internally, decides it wants to initialize
> another ares_channel with the same options as one that already exists. If
> he/it uses the old ares_save_options() the newstyle options won't be copied
> so a ares_save_newstyle_options() is required.

Yeah, the save and use options things are really not very fun to get working
nicely...

> We have duplicated all the external functions which had an ares_options
> struct argument, and also introduced ares_setopt(). Not to mention the
> increased complexity that the library internals will suffer.

I sense a negative attitude to this idea here... What approach do you think is
the better way forward then?

In my view there's _not_ much internal complexity added by this, only a little
"juggling" to get the two ways of setting options combined at a price that is
a few new functions and a somewhat confusing API to start with.

This pain should be decreased in the future once we can set all options the
same way and we can deprecate the older way.

I want us to figure out a way to migrate the API to something that will
survive easier. I'm not saying my suggestions are the only solutions nor that
they are perfect in any way, but I'm not seeing a lot of other alternatives
being suggested.

> Let's suppose that such a setup is released. When will we be able to get rid
> of the external ares_options struct (which was one of the goals of all this
> change)? I presume that never as it would be an API/ABI breakage. And we
> will have to live with the duplicate/separate options and internal
> complexity forever long. And people wondering why there are duplicate
> functions to handle the options stuff.

First I think we should make it possible to set all options using the new way
(which might take a while depending on the size of the developer hoard that
will take onthis task :-) ), then we can think about deprecating the old way.

When the new API has worked for a release or two I think we can consider
cutting out the ares_options struct and do the actual ABI bump and cut out the
public config struct for good. Or something like that.

-- 
  / daniel.haxx.se
Received on 2008-11-28