Foundationdb FDB_API_VERSION version from bindings

Hi!

I maintain the nodejs bindings for foundationdb. Because the nodejs bindings are maintained and published out-of-tree, there’s a decoupling between which version of the node bindings people are using and which version of the foundationdb database people are using. So versioning is tricky. There are 4 different version numbers in play:

  • The version of the foundationdb database (server and client). Eg 6.2.15
  • The version of the nodejs foundationdb library. Eg 1.1.2.
  • The ‘runtime API version’ the client selects
  • The ‘header API version’ which node-foundationdb is compiled against

Every time I come back to this, I’m always confused about how those numbers all interact. For example, the foundationdb library sets the C “header version” via FDB_API_VERSION. How is this related to the application version?

Looks like runtime version <= header version, and header version <= libfdb_c.

We recently added support for API version 630 to the nodejs library, which included updating the header version (via #define FDB_API_VERSION 630). Unfortunately, this has caused problems for users running older versions of foundationdb.

Q:

What header version should I be setting in the node foundationdb bindings?

Should I:

  1. Tell users to match node-foundationdb with the version of the foundationdb database they have installed? This is unfortunate coupling. I don’t have the time or interest in maintaining a tableau of versions of the bindings for each version of the fdb API. Is there a chart anywhere showing which versions will work with which other versions? I’m happy to set a minimum supported fdb version for node-foundationdb, so long as its something reasonable.
  2. Use fdb_select_api_version_impl and force the issue? Would this cause weird issues?
  3. Be pessimistic with API versions, and just wait 6 months - 1 year before supporting new API features in node-foundationdb, to maintain more compatibility with older database versions?
  4. ???
1 Like

The header version declares what API your binding code expects from the fdb_c native client library. You’ll need this to match the latest version to get some of the latest changes, but that also means you can’t use it with old client versions that don’t expose the newest API. The runtime version is intended to determine what API the client application expects from the client library (and possibly from your bindings, if you want to use it that way). The idea is that an application declaring API version X should continue to work the same way if you upgrade your database or your bindings.

The approach that the official bindings take is that a new version of the bindings is released with each new FDB version. The new bindings can only be used on the new FDB version because of the header version requirement.

If you don’t want to manage multiple versions, your other ideas could be made to work. You could have your bindings stick with the oldest version that you want to support and delay introduction of new API-version dependent changes.

You could also try to pick a header version dynamically, but that might require you to have some extra logic to deal with changes in the underlying library behavior when you do. For example, if a C function signature were to change, you would have to call it with the correct arguments depending on the version you chose. This is going to be easier to accomplish in some languages than others.