App compatibility in Corda
This useful blog post on Apple’s app compatibility approach reminded me that we haven’t done much explaining of our own approach to this issue.
Apple has put hundreds of workarounds into their operating systems for bugs in popular apps. It’s common enough: Microsoft is the reigning high king of this sort of thing, but nVidia & AMD also hot-patch bugs in video games from inside the drivers.
Many developers feel this sort of thing is dirty or a bad idea, but I’m not one of them. Open source platforms typically don’t do app-specific workarounds. Such platforms are usually bundled with apps and not sold, so there’s not much incentive to make upgrades as easy as possible. The developers often care more about other things - it’s not like they earn more money the more popular their new version is. But the fact that every major proprietary platform vendor does it is suggestive; it’s too hard for users to upgrade complex platforms if you don’t do these workarounds, as complex apps inevitably have bugs exposed by changes in the underlying platforms.
One of the things we’re planning on working on over the summer is upgrades to Corda’s versions and modules support. As part of this we’ll be introducing the notion of a “target version”. The same concept exists in iOS and Android. Apps declare what version of the platform they were tested against. By increasing the target version apps can progressively ‘opt out’ of workarounds. That’s useful because usually the platform changed for a reason, and if it has to un-change because of buggy apps then other developers end up suffering. Thus being able to detect apps that need workarounds is helpful.
Target versioning is one of the techniques we plan to use to keep apps working in the face of platform upgrades. Here are others:
I want to set expectations now because it’s unconventional for open source projects to go to the same lengths that Apple and Microsoft do.
Sometimes people ask if appcompat workarounds hurt a platform for ‘well behaved’ apps? My experience has been no; appcompat checking has a relatively small impact on performance and maintainability. As Raymond Chen argues here, the real cost of compatibility comes in the design phase where you have to change how features work in order to preserve compatibility with your existing feature set. But that’s inevitable for any deployed system, so the incremental cost of going the extra mile isn’t that high: it’s pretty common for developers to argue that a function here or class there has to be changed, there just isn’t any other way to do it, and then on inspection it turns out that it’s not so hard to remain compatible. People just prefer not to do it. That’s why we enforce API/ABI checks via merge gates.
However, the targetVersion mechanism means that when the app’s target is high enough, old appcompat tricks can be disabled or removed entirely (e.g. by linking against core modules that don’t have them).
There is a flip side to all of this. The reason we will go the extra mile around compatibility is because the nature of Corda as a shared system means you may sometimes be asked to upgrade your node, even if there’s no benefit to yourself – i.e. in order to activate features other people want to use which your node must be able to validate. The deal is, we bend over backwards to make upgrades easy, and you in turn accept that you can’t keep your servers running a 10 year old node because that happens to be convenient for your internal budgeting process. We anticipate that some compatibility zones, like the main Corda network, will set policies around mandatory upgrade schedules to keep things moving.