Don't do app upgrades in the background

This removes the logic for transparently upgrading apps and moves it to the same system we use for core upgrades.
Transparent app upgrades can leave the instance in a broken state when requests are being processed in parallel.

Only doing the upgrades in the foreground prevents this and provide a way for users to know when an upgrade failed.

cc @DeepDiver1975 @PVince81 
I mean you didn't just copy paste the code, so this is a note that we'll need to regression test app compatibility as well.