Currently snapshots are promoted by creating and removing snapshot childs (which pair up a snapshot to a fragment and fragment version). This means the model currently looks like:
Snapshot 1 -> * Snapshot Child
It's potentially possible to retrieve all snapshot childs for a snapshot, while a snapshot is being promoted and get an inconsistent state. Instead it should be remodelled to look like:
Snapshot 1 -> 1 Snapshot Ref 1 -> * Snapshot Child
The snapshot contains the snapshot name, and a snapshot reference PHID. Snapshot child is updated to also use snapshot reference instead of snapshot.
When promoting a snapshot, a new snapshot reference is created, along with new snapshot child entries. Once that snapshot reference and children have been fully written, we update the snapshot to point to the new snapshot reference. After this, we delete the old snapshot reference and the child entries.
This ensures that when you read the snapshot, you always get a consistent snapshot ref (it's either the old version or new version). We should probably use a global lock around the deletion or some mechanism to ensure that we don't delete while querying for the children of the old reference, but at least in this behaviour the promotion is asynchronous to the snapshot reads (only the deletion of old snapshot reference is blocked, not the promotion of the new content).