hollow/src/main/java/com/netflix/hollow/api/producer/AbstractHollowProducer.java
void publish(ListenerSupport.Listeners listeners, long toVersion, Artifacts artifacts) throws IOException {
        Status.StageBuilder psb = listeners.firePublishStart(toVersion);
        try {
            artifacts.snapshot = stageBlob(listeners,
                    blobStager.openSnapshot(toVersion));

            if (readStates.hasCurrent()) {
                artifacts.delta = stageBlob(listeners,
                        blobStager.openDelta(readStates.current().getVersion(), toVersion));
                artifacts.reverseDelta = stageBlob(listeners,
                        blobStager.openReverseDelta(toVersion, readStates.current().getVersion()));

                publishBlob(listeners, artifacts.delta);
                publishBlob(listeners, artifacts.reverseDelta);

                if (--numStatesUntilNextSnapshot < 0) {
                    if (snapshotPublishExecutor == null) {
                        publishBlob(listeners, artifacts.snapshot);
                        artifacts.markSnapshotPublishComplete();
                    } else {
                        // Submit the publish blob task to the executor
                        publishSnapshotBlobAsync(listeners, artifacts);
                    }
                    numStatesUntilNextSnapshot = numStatesBetweenSnapshots;
                } else {
                    artifacts.markSnapshotPublishComplete();
                }
            } else {
                publishBlob(listeners, artifacts.snapshot);
                artifacts.markSnapshotPublishComplete();
                numStatesUntilNextSnapshot = numStatesBetweenSnapshots;
            }

            psb.success();
        } catch (Throwable throwable) {
            psb.fail(throwable);
            throw throwable;
        } finally {
            listeners.firePublishComplete(psb);
        }
    }
void publish(ListenerSupport.Listeners listeners, long toVersion, Artifacts artifacts) throws IOException {
        Status.StageBuilder psb = listeners.firePublishStart(toVersion);
        try {
            artifacts.snapshot = stageBlob(listeners,
                    blobStager.openSnapshot(toVersion));

            if (readStates.hasCurrent()) {
                artifacts.delta = stageBlob(listeners,
                        blobStager.openDelta(readStates.current().getVersion(), toVersion));
                artifacts.reverseDelta = stageBlob(listeners,
                        blobStager.openReverseDelta(toVersion, readStates.current().getVersion()));

                publishBlob(listeners, artifacts.delta);
                publishBlob(listeners, artifacts.reverseDelta);

                if (--numStatesUntilNextSnapshot < 0) {
                    if (snapshotPublishExecutor == null) {
                        publishBlob(listeners, artifacts.snapshot);
                        artifacts.markSnapshotPublishComplete();
                    } else {
                        // Submit the publish blob task to the executor
                        publishSnapshotBlobAsync(listeners, artifacts);
                    }
                    numStatesUntilNextSnapshot = numStatesBetweenSnapshots;
                } else {
                    artifacts.markSnapshotPublishComplete();
                }
            } else {
                publishBlob(listeners, artifacts.snapshot);
                artifacts.markSnapshotPublishComplete();
                numStatesUntilNextSnapshot = numStatesBetweenSnapshots;
            }

            psb.success();
        } catch (Throwable throwable) {
            psb.fail(throwable);
            throw throwable;
        } finally {
            listeners.firePublishComplete(psb);
        }
    }
/*
Publish the write state, storing the artifacts in the provided object. Visible for testing.