@Nullable
  public static <T> T waitForFinalResult(DataSource<T> dataSource, long timeout, TimeUnit unit)
      throws Throwable {
    final CountDownLatch latch = new CountDownLatch(1);
    final ValueHolder<T> resultHolder = new ValueHolder<>();
    final ValueHolder<Throwable> pendingException = new ValueHolder<>();

    dataSource.subscribe(
        new DataSubscriber<T>() {
          @Override
          public void onNewResult(DataSource<T> dataSource) {
            // only return the final result
            if (!dataSource.isFinished()) {
              return;
            }

            try {
              resultHolder.value = dataSource.getResult();
            } finally {
              latch.countDown();
            }
          }

          @Override
          public void onFailure(DataSource<T> dataSource) {
            try {
              pendingException.value = dataSource.getFailureCause();
            } finally {
              latch.countDown();
            }
          }

          @Override
          public void onCancellation(DataSource<T> dataSource) {
            // will make the outer method return null
            latch.countDown();
          }

          @Override
          public void onProgressUpdate(DataSource<T> dataSource) {
            // intentionally left blank
          }
        },
        new Executor() {
          @Override
          public void execute(Runnable command) {
            // it's fair to run these short methods on the datasource thread to avoid
            // context switching
            command.run();
          }
        });

    // wait for countdown() by the DataSubscriber
    if (timeout < 0) {
      latch.await();
    } else {
      if (!latch.await(timeout, unit)) {
        throw new TimeoutException();
      }
    }

    // if the data source failed, throw its exception
    if (pendingException.value != null) {
      throw pendingException.value;
    }

    return resultHolder.value;
  }
This methods blocks the calling thread until the {@link DataSource} has a final result, has
been cancelled or has failed.

@param dataSource The {@link DataSource} to wait for. The caller MUST close the data source
    after this method returned!
@param <T> The type parameter for the {@link DataSource}
@param timeout The maximum time to wait for the final result
@param unit The time unit of the timeout argument
@return The final result of the {@link DataSource}. Intermediate results are ignored. Might be
    <code>null</code> if the data source has been cancelled.
@throws Throwable if the {@link DataSource} has failed
fbcore/src/main/java/com/facebook/datasource/DataSources.java