RFR: 381: Retry failed materialization of hosted repository storage

Jorn Vernee jvernee at openjdk.java.net
Thu May 7 11:44:23 UTC 2020


On Mon, 4 May 2020 14:08:31 GMT, Robin Westberg <rwestberg at openjdk.org> wrote:

> Hi all,
> 
> Please review this change that improves the reliability of the initial materialization of hosted repository storage.
> 
> Best regards,
> Robin

Had to look at this a bit since the control flow is a bit confusing with the early `return` from the constructor. How
about putting the retry logic into a separate helper method? This is what I came up with:

HostedRepositoryStorage(HostedRepository repository, Path localStorage, String ref, String fileName, String authorName,
String authorEmail, String message, StorageSerializer<T> serializer, StorageDeserializer<T> deserializer) {
    this.hostedRepository = repository;
    this.ref = ref;
    this.fileName = fileName;
    this.authorEmail = authorEmail;
    this.authorName = authorName;
    this.message = message;
    this.serializer = serializer;
    this.deserializer = deserializer;

    this.localRepository = tryMaterialize(localStorage);
    repositoryStorage = new RepositoryStorage<>(localRepository, fileName, authorName, authorEmail, message, serializer,
    deserializer); current = current();
}

private Repository tryMaterialize(Path localStorage) {
    int retryCount = 0;
    IOException lastException = null;

    while (retryCount < 10) {
        try {
            try {
                return Repository.materialize(localStorage, hostedRepository.url(), "+" + ref + ":storage");
            } catch (IOException ignored) {
                // The remote ref may not yet exist
                Repository localRepository = Repository.init(localStorage, hostedRepository.repositoryType());
                var storage = Files.writeString(localStorage.resolve(fileName), "");
                localRepository.add(storage);
                var firstCommit = localRepository.commit(message, authorName, authorEmail);

                // If the materialization failed for any other reason than the remote ref not existing, this will fail
                localRepository.push(firstCommit, hostedRepository.url(), ref);
                return localRepository;
            }
        } catch (IOException e) {
            lastException = e;
        }
        retryCount++;
    }
    throw new UncheckedIOException("Retry count exceeded", lastException);
}
This would also allow keeping `localRepository` as a `final` field. What do you think?

-------------

Marked as reviewed by jvernee (Reviewer).

PR: https://git.openjdk.java.net/skara/pull/617


More information about the skara-dev mailing list