Search in sources :

Example 1 with WorkersCallback

use of build.buildfarm.instance.shard.ShardInstance.WorkersCallback in project bazel-buildfarm by bazelbuild.

the class RemoteInputStreamFactory method newInput.

@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
public InputStream newInput(Digest blobDigest, long offset, long deadlineAfter, TimeUnit deadlineAfterUnits, RequestMetadata requestMetadata) throws IOException, InterruptedException {
    Set<String> remoteWorkers;
    Set<String> locationSet;
    try {
        Set<String> workers = backplane.getWorkers();
        if (publicName == null) {
            remoteWorkers = workers;
        } else {
            synchronized (workers) {
                remoteWorkers = Sets.difference(workers, ImmutableSet.of(publicName)).immutableCopy();
            }
        }
        locationSet = Sets.newHashSet(Sets.intersection(backplane.getBlobLocationSet(blobDigest), workers));
    } catch (IOException e) {
        throw Status.fromThrowable(e).asRuntimeException();
    }
    if (publicName != null && locationSet.remove(publicName)) {
        backplane.removeBlobLocation(blobDigest, publicName);
    }
    List<String> workersList = new ArrayList<>(locationSet);
    boolean emptyWorkerList = workersList.isEmpty();
    final ListenableFuture<List<String>> populatedWorkerListFuture;
    if (emptyWorkerList) {
        populatedWorkerListFuture = transform(correctMissingBlob(backplane, remoteWorkers, locationSet, this::workerStub, blobDigest, newDirectExecutorService(), requestMetadata), (foundOnWorkers) -> {
            Iterables.addAll(workersList, foundOnWorkers);
            return workersList;
        }, directExecutor());
    } else {
        populatedWorkerListFuture = immediateFuture(workersList);
    }
    SettableFuture<InputStream> inputStreamFuture = SettableFuture.create();
    addCallback(populatedWorkerListFuture, new WorkersCallback(rand) {

        boolean triedCheck = emptyWorkerList;

        @Override
        public void onQueue(Deque<String> workers) {
            Set<String> locationSet = Sets.newHashSet(workers);
            boolean complete = false;
            while (!complete && !workers.isEmpty()) {
                try {
                    inputStreamFuture.set(fetchBlobFromRemoteWorker(blobDigest, workers, offset, deadlineAfter, deadlineAfterUnits, requestMetadata));
                    complete = true;
                } catch (IOException e) {
                    if (workers.isEmpty()) {
                        if (triedCheck) {
                            onFailure(e);
                            return;
                        }
                        triedCheck = true;
                        workersList.clear();
                        ListenableFuture<List<String>> checkedWorkerListFuture = transform(correctMissingBlob(backplane, remoteWorkers, locationSet, RemoteInputStreamFactory.this::workerStub, blobDigest, newDirectExecutorService(), requestMetadata), (foundOnWorkers) -> {
                            Iterables.addAll(workersList, foundOnWorkers);
                            return workersList;
                        }, directExecutor());
                        addCallback(checkedWorkerListFuture, this, directExecutor());
                        complete = true;
                    }
                } catch (InterruptedException e) {
                    complete = true;
                    onFailure(e);
                }
            }
        }

        @SuppressWarnings("NullableProblems")
        @Override
        public void onFailure(Throwable t) {
            Status status = Status.fromThrowable(t);
            if (status.getCode() == Code.NOT_FOUND) {
                inputStreamFuture.setException(new NoSuchFileException(DigestUtil.toString(blobDigest)));
            } else {
                inputStreamFuture.setException(t);
            }
        }
    }, directExecutor());
    try {
        return inputStreamFuture.get();
    } catch (ExecutionException e) {
        Throwable cause = e.getCause();
        Throwables.throwIfUnchecked(cause);
        Throwables.throwIfInstanceOf(cause, IOException.class);
        Throwables.throwIfInstanceOf(cause, InterruptedException.class);
        throw new UncheckedExecutionException(cause);
    }
}
Also used : Iterables(com.google.common.collect.Iterables) NoSuchFileException(java.nio.file.NoSuchFileException) LoadingCache(com.google.common.cache.LoadingCache) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) MoreExecutors.newDirectExecutorService(com.google.common.util.concurrent.MoreExecutors.newDirectExecutorService) RequestMetadata(build.bazel.remote.execution.v2.RequestMetadata) Random(java.util.Random) Util.correctMissingBlob(build.buildfarm.instance.shard.Util.correctMissingBlob) InputStreamFactory(build.buildfarm.common.InputStreamFactory) SettableFuture(com.google.common.util.concurrent.SettableFuture) Deque(java.util.Deque) DigestUtil(build.buildfarm.common.DigestUtil) ArrayList(java.util.ArrayList) Level(java.util.logging.Level) SHARD_IS_RETRIABLE(build.buildfarm.instance.shard.Util.SHARD_IS_RETRIABLE) Code(io.grpc.Status.Code) Futures.addCallback(com.google.common.util.concurrent.Futures.addCallback) Digest(build.bazel.remote.execution.v2.Digest) UncheckedExecutionException(com.google.common.util.concurrent.UncheckedExecutionException) Status(io.grpc.Status) Nullable(javax.annotation.Nullable) WorkersCallback(build.buildfarm.instance.shard.ShardInstance.WorkersCallback) Backplane(build.buildfarm.backplane.Backplane) Futures.immediateFuture(com.google.common.util.concurrent.Futures.immediateFuture) ImmutableSet(com.google.common.collect.ImmutableSet) Throwables(com.google.common.base.Throwables) Set(java.util.Set) IOException(java.io.IOException) Logger(java.util.logging.Logger) Instance(build.buildfarm.instance.Instance) Sets(com.google.common.collect.Sets) MoreExecutors.directExecutor(com.google.common.util.concurrent.MoreExecutors.directExecutor) StatusRuntimeException(io.grpc.StatusRuntimeException) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) Futures.transform(com.google.common.util.concurrent.Futures.transform) SECONDS(java.util.concurrent.TimeUnit.SECONDS) InputStream(java.io.InputStream) Status(io.grpc.Status) ImmutableSet(com.google.common.collect.ImmutableSet) Set(java.util.Set) UncheckedExecutionException(com.google.common.util.concurrent.UncheckedExecutionException) InputStream(java.io.InputStream) ArrayList(java.util.ArrayList) NoSuchFileException(java.nio.file.NoSuchFileException) IOException(java.io.IOException) WorkersCallback(build.buildfarm.instance.shard.ShardInstance.WorkersCallback) ArrayList(java.util.ArrayList) List(java.util.List) UncheckedExecutionException(com.google.common.util.concurrent.UncheckedExecutionException) ExecutionException(java.util.concurrent.ExecutionException)

Aggregations

Digest (build.bazel.remote.execution.v2.Digest)1 RequestMetadata (build.bazel.remote.execution.v2.RequestMetadata)1 Backplane (build.buildfarm.backplane.Backplane)1 DigestUtil (build.buildfarm.common.DigestUtil)1 InputStreamFactory (build.buildfarm.common.InputStreamFactory)1 Instance (build.buildfarm.instance.Instance)1 WorkersCallback (build.buildfarm.instance.shard.ShardInstance.WorkersCallback)1 SHARD_IS_RETRIABLE (build.buildfarm.instance.shard.Util.SHARD_IS_RETRIABLE)1 Util.correctMissingBlob (build.buildfarm.instance.shard.Util.correctMissingBlob)1 Throwables (com.google.common.base.Throwables)1 LoadingCache (com.google.common.cache.LoadingCache)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 Iterables (com.google.common.collect.Iterables)1 Sets (com.google.common.collect.Sets)1 Futures.addCallback (com.google.common.util.concurrent.Futures.addCallback)1 Futures.immediateFuture (com.google.common.util.concurrent.Futures.immediateFuture)1 Futures.transform (com.google.common.util.concurrent.Futures.transform)1 ListenableFuture (com.google.common.util.concurrent.ListenableFuture)1 MoreExecutors.directExecutor (com.google.common.util.concurrent.MoreExecutors.directExecutor)1 MoreExecutors.newDirectExecutorService (com.google.common.util.concurrent.MoreExecutors.newDirectExecutorService)1