And, as Tim mentioned, updating symlinks is the way to do an atomic cut-over from one deployment to the next. The Puppet Compiler de-references symlinks at the start of compilation, so any in-flight requests should continue using the older versions.
You just need some sort of sweeper that runs in the background to clean those up after some reasonable interval (1 hour should be fine, if you've got a catalog compilation taking longer than that, you have a performance problem that is being ignored).