All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.yahoo.maha.parrequest2.future.ParRequest Maven / Gradle / Ivy

There is a newer version: 6.158
Show newest version
// Copyright 2017, Yahoo Holdings Inc.
// Licensed under the terms of the Apache License 2.0. Please see LICENSE file in project root for terms.
package com.yahoo.maha.parrequest2.future;

import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.yahoo.maha.parrequest2.EitherUtils;
import com.yahoo.maha.parrequest2.ParCallable;
import scala.util.Either;
import com.yahoo.maha.parrequest2.GeneralError;
import scala.Option;
import scala.Function1;
import scala.Unit;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

/**
 * This class represents a parallel request which can be composed synchronously with resultMap, or composed
 * asynchronously with map and fold
 */
public class ParRequest extends CombinableRequest {

    private final ParallelServiceExecutor executor;
    private final ListenableFuture> future;

    ParRequest(String label, ParallelServiceExecutor executor, ParCallable> request) {
        checkNotNull(executor, "Executor is null");
        checkNotNull(request, "Request is null");
        this.label = label;
        this.executor = executor;

        //fire request
        this.future = executor.submitParCallable(request);
    }

    ParRequest(String label, ParallelServiceExecutor executor, ListenableFuture> future) {
        checkNotNull(executor, "Executor is null");
        checkNotNull(future, "Future is null");
        this.label = label;
        this.executor = executor;

        this.future = future;
    }

    public  Either resultMap(ParFunction fn) {
        Either result = executor.getEitherSafely(label, future);
        return EitherUtils.map(fn, result);
    }

    public  NoopRequest fold(ParFunction errFn, ParFunction fn) {
        return new NoopRequest<>(executor, new FoldableFuture<>(executor, future, fn, errFn));
    }

    /**
     * The reason we need a label here is because we are creating a new ParRequest.
     */
    public  ParRequest map(String label, ParFunction> fn) {
        return new ParRequest(label, executor, new ComposableFuture<>(executor, future, fn));
    }

    /**
     * *
     */
    public  ParRequest flatMap(String label, ParFunction> fn) {
        return new ParRequest(label, executor, new ComposableFutureFuture<>(executor, future, fn));
    }

    public Either get(long timeoutMillis) {
        return executor.getEitherSafely(label, future, timeoutMillis);
    }

    public Either get() {
        return executor.getEitherSafely(label, future);
    }

    ListenableFuture> asFuture() {
        return future;
    }

    public static class Builder {

        private final ParallelServiceExecutor executor;
        private Option>> parCallable = Option.empty();
        private boolean built = false;
        private String label = "changethis";

        public Builder(ParallelServiceExecutor executor) {
            this.executor = executor;
        }

        public Builder setParCallable(ParCallable> parCallable) {
            checkState(this.parCallable.isEmpty(), "Cannot set the parCallable twice!");
            this.parCallable = Option.apply(parCallable);
            return this;
        }

        public Builder with(Function1> fn1) {
            checkState(this.parCallable.isEmpty(), "Cannot set the parCallable twice!");
            this.parCallable = Option.apply(ParCallable.fromScala(fn1));
            return this;
        }


        public Builder setLabel(String label) {
            this.label = label;
            return this;
        }

        public ParRequest build() {
            checkState(!built, "Cannot build a request twice!");
            checkState(parCallable.isDefined(), "ParCallable not defined!");
            try {
                ParCallable> first = ParCallable.from(parCallable.get());
                return new ParRequest<>(label, executor, first);
            } finally {
                built = true;
            }
        }
    }

    public static  ParRequest immediateResult(String label, ParallelServiceExecutor executor,
                                                    Either t) {
        checkNotNull(t, "result is null");
        checkNotNull(executor, "Executor is null");
        return new ParRequest(label, executor, Futures.immediateFuture(t));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy