While I understand the desire to keep APIs backwards compatible (we generally do with
our clients), that won't always be the case, and having N functions that do the same
thing and exist for backwards compatibility reasons will be quite confusing.
On top of that, it *increases* the burden of compatibility maintenance in the long run
because now instead of maintaining 1 function that takes all the possible arguments for
a method, you have to maintain N.
So no, please don't introduce amqp_exchange_declare2 and so on.
This is not a major change, so please update and re-compile the code that depends on it
and lets move on to more interesting things.
On 26 February 2015 at 11:21:27, Elias Mårtenson (lok...@gmail.com) wrote:
> C libraries generally never do this, and the way this is generally dealt with is to increase the major version
> number of the shared object file
Even for a single function signature change? I think breaking the API of 1 function is not unreasonable
for a minor release. I understand that this is more painful in native code than, say, on the JVM or .NET.
For pure C projects, I suspect that static compilation can be an answer. Just so that we understand,
what about Common Lisp? Is there a way to statically compile a binary with most of code in CL and
some C libraries?
On 26 February 2015 at 11:42:03, Elias Mårtenson (lok...@gmail.com) wrote:
> In other words, not only do you need to recompile every single
> program that uses the library.
This makes sense.
Why don't we just bump the version, has librabbitmq done this much in the past?
As I was looking through the commit log of rabbitmq-c I noticed commit id 9626dd5cd5f78894f1416a1afd2d624ddd4904ae which adds two new parameters to the function amqp_exchange_declare(). This is a compatibility-breaking change, and I was wondering how this will be handled once this version is released?
This is particularly nasty for the Common Lisp API which is built on this, since still change will not even cause compile errors (the Lisp runtime directly loads shared object and calls the function based on its own function declaration which is now incompatible with the new version of rabbitmq-c) but instead cause a crash (if we're lucky).
Wouldn't it make more sense to introduce a new call, similar to what was done for amqp_error_string2() in order to preserve compatibility?
Yes, this is an ABI-breaking change. As such the SONAME for the library was incremented. This should prevent binaries that link against an older SONAME from loading the new version of the library. A note was also made in the release notes. FYI: this was released as a part of v0.6.0.
If your code doesn't already: I would make sure that it validates the SONAME of whatever its loading. I do make every effort to make the SONAME reflect non-backwards compatible ABI changes. There are methods to get the version of the library at runtime: amqp_version and amqp_version_number, though those values give you the API version and not the ABI version.
Wouldn't it make more sense to introduce a new call, similar to what was done for amqp_error_string2() in order to preserve compatibility?The short answer is: I don't believe rabbitmq-c is mature enough to warrant maintaining perfect ABI backward compatibility at the cost of adding API complexity at this point. (amqp_error_string2 is one example of a mistake that was made).
This increases the complexity to the public API increasing the maintenance burden, but more importantly makes the library harder to use: even with documentation as a consumer of the library it becomes more difficult to determine how to use the library 'correctly'.
I hope that one day I can push rabbitmq-c to a level of API maturity and feature completeness that I'm confident new features can be added without breaking the ABI. At this point I will give it the v1.0.0 label in semantic versioning parlance, and maintaining ABI backward compatibility will become a priority once again.
That said: I do understand that there are users of rabbitmq-c, and as such I'll try make it obvious when breaking changes are made to the library by continuing to increment the SONAME as necessary and clearly documenting what has changed.
On 27 February 2015 at 10:57, Alan Antonuk <alan.a...@gmail.com> wrote:Yes, this is an ABI-breaking change. As such the SONAME for the library was incremented. This should prevent binaries that link against an older SONAME from loading the new version of the library. A note was also made in the release notes. FYI: this was released as a part of v0.6.0.Thank you for this clarification. I haven't actually compiled the latest version yet, but I can assume it's librabbitmq.so.2 now, yes?
If your code doesn't already: I would make sure that it validates the SONAME of whatever its loading. I do make every effort to make the SONAME reflect non-backwards compatible ABI changes. There are methods to get the version of the library at runtime: amqp_version and amqp_version_number, though those values give you the API version and not the ABI version.Right now, I simply load librabbitmq.so, which clearly isn't ideal. I will change this to explicitly load librabbitmq.so.1 instead to at least avoid random crashes.I need to change the code to check for library version so that I can do the right thing regardless of what version the user has installed.Do you collect a complete list of breaking changes so that I can keep cl-rabbit up to date? Especially for function argument list changes, this is more important for CL than for traditional C code, since I'm not compiling against the prototypes in the .h file, but I rather have to define the argument lists like this.
Wouldn't it make more sense to introduce a new call, similar to what was done for amqp_error_string2() in order to preserve compatibility?The short answer is: I don't believe rabbitmq-c is mature enough to warrant maintaining perfect ABI backward compatibility at the cost of adding API complexity at this point. (amqp_error_string2 is one example of a mistake that was made).Fair enough. However, this begs the question as to what the future will look like. Do you foresee lots of breaking changes before you hit 1.0?
This increases the complexity to the public API increasing the maintenance burden, but more importantly makes the library harder to use: even with documentation as a consumer of the library it becomes more difficult to determine how to use the library 'correctly'.Another alternative would be to add things in a backward-compatible manner until you hit 1.0, at which point all backwards compatibility is dropped at once with 1.0 being a completely cleaned-up API.I hope that one day I can push rabbitmq-c to a level of API maturity and feature completeness that I'm confident new features can be added without breaking the ABI. At this point I will give it the v1.0.0 label in semantic versioning parlance, and maintaining ABI backward compatibility will become a priority once again.I'm certainly OK with bending backwards a bit extra to maintain cl-rabbit compatibility until 1.0, but if that is very far off in time, or if there is lots of incremental breakage, that may be simply too much and I would have to lock cl-rabbit to a specific version of rabbitmq-c, which would be unfortunate but probably better than not having a stable product.That said: I do understand that there are users of rabbitmq-c, and as such I'll try make it obvious when breaking changes are made to the library by continuing to increment the SONAME as necessary and clearly documenting what has changed.Yes, at least this is workable.Speaking of adoption, the biggest user of cl-rabbit right now is the project I'm working on myself (which is in limited production right now). Based on the feedback I have received there are are at least a couple of other people who have been trying it out. Whether it's actively being used in production anywhere else, I cannot say, but given the fact that the project is new, I'd say probably not.Finally, I have to extend my thanks to you for building this product in the first place. Without it, there would be no reasonable way to use RabbitMQ from CL, short of reimplementing the entire protocol. This solution has proven to be incredibly stable for us so far, having had exactly zero issues with messaging in our application since migrating from zeromq to RabbitMQ.
Regards,Elias