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

org.javabits.yar.guice.NoWaitBlockingSupplier Maven / Gradle / Ivy

There is a newer version: 3.0.1.RELEASE
Show newest version
package org.javabits.yar.guice;

import static com.google.common.util.concurrent.Futures.addCallback;
import static org.javabits.yar.Registry.DEFAULT_TIMEOUT;
import static org.javabits.yar.Registry.DEFAULT_TIME_UNIT;

import java.lang.InterruptedException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;

import javax.annotation.Nullable;

import com.google.common.base.*;
import org.javabits.yar.*;

import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
import org.javabits.yar.Supplier;

/**
 * @author Romain Gilles Date: 5/31/13 Time: 2:08 PM
 */
public class NoWaitBlockingSupplier implements BlockingSupplier, SupplierListener, SupplierWrapper {

    private final Id id;
    private final AtomicReference> supplierReference;
    private final AtomicReference>> supplierFutureRef;

    public NoWaitBlockingSupplier(Id id, final Supplier supplier) {
        this.id = id;
        supplierReference = new AtomicReference<>(supplier);
        supplierFutureRef = new AtomicReference<>();
        SettableFuture> settableFuture = SettableFuture.create();
        supplierFutureRef.set(settableFuture);
        if (supplier != null) {
            settableFuture.set(supplier);
        }
    }

    @Nullable
    @Override
    public T get() {
        Supplier supplier = supplierReference.get();
        return supplier != null ? supplier.get() : null;
    }

    @Override
    public T getSync() throws InterruptedException {
        return get();
    }

    @Override
    public T getSync(long timeout, TimeUnit unit) throws InterruptedException, TimeoutException {
        return get();
    }

    @Override
    public ListenableFuture getAsync() {
        final SettableFuture future = SettableFuture.create();
        // The future callback will be executed either on the current thread (if the future is
        // already completed) or on the registry's action handler thread.
        addCallback(supplierFutureRef.get(), new FutureCallback>() {
            @Override
            public void onSuccess(Supplier supplier) {
                future.set(supplier.get());
            }

            @Override
            public void onFailure(Throwable t) {
            }
        });
        return future;
    }

    @Override
    public long defaultTimeout() {
        return DEFAULT_TIMEOUT;
    }

    @Override
    public TimeUnit defaultTimeUnit() {
        return DEFAULT_TIME_UNIT;
    }

    @Override
    public Id id() {
        return id;
    }

    @Nullable
    @Override
    public com.google.common.base.Supplier getNativeSupplier() {
        return supplierReference.get();
    }

    /**
     * there no thread safety issue because the supplierFutureRef is only used for the
     * asynchronous approach. The risk is small enough to avoid to introduce more complexity.
     */
    @Override
    public void supplierChanged(SupplierEvent supplierEvent) {
        SupplierEvent.Type type = supplierEvent.type();
        Supplier supplier = (Supplier) supplierEvent.supplier();
        switch (type) {
        case ADD:
            if (supplierReference.compareAndSet(null, supplier)) {
                supplierFutureRef.get().set(supplier);
            }
            break;
        case REMOVE:
            if (supplierReference.compareAndSet(supplier, null)) {
                supplierFutureRef.set(SettableFuture.> create());
            }
            break;
        default:
            throw new IllegalStateException("Unknown supplier event: " + supplierEvent);
        }
    }

    @Override
    public com.google.common.base.Supplier getWrapped() {
        return getNativeSupplier();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy