public File waitFor(FileReference fileReference, long timeout, TimeUnit timeUnit) throws InterruptedException {
        Timer timer = new Timer(timeout, timeUnit);
        do {
            Target target = connection.getTarget(timer);
            if (target == null)
                break;

            Request request = new Request("waitFor");
            request.parameters().add(new StringValue(fileReference.value()));

            double rpcTimeout = Math.min(timer.timeLeft(TimeUnit.SECONDS), 60.0);
            log.log(Level.FINE, () -> "InvokeSync waitFor " + fileReference + " with " + rpcTimeout + " seconds timeout");
            target.invokeSync(request, rpcTimeout);

            if (request.checkReturnTypes("s")) {
                return new File(request.returnValues().get(0).asString());
            } else if (!request.isError()) {
                throw new RuntimeException("Invalid response: " + request.returnValues());
            } else if (temporaryError(request.errorCode())) {
                log.log(Level.INFO, "Retrying waitFor for " + fileReference + ": " + request.errorCode() + " -- " + request.errorMessage());
                Thread.sleep(1000);
            } else {
                throw new RuntimeException("Wait for " + fileReference + " failed: " + request.errorMessage() + " (" + request.errorCode() + ")");
            }
        } while ( timer.isTimeLeft() );

        throw new TimeoutException("Timed out waiting for " + fileReference + " after " + timeout + " " + timeUnit.name().toLowerCase());
    }
Returns the path to a file or directory corresponding to the
given file reference.  File references are produced by the
config system.

@throws TimeoutException if the file or directory could not be retrieved in time.
fileacquirer/src/main/java/com/yahoo/filedistribution/fileacquirer/FileAcquirerImpl.java