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

org.sputnikdev.bluetooth.manager.impl.CompletableFutureService Maven / Gradle / Ivy

package org.sputnikdev.bluetooth.manager.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sputnikdev.bluetooth.manager.BluetoothGovernor;
import org.sputnikdev.bluetooth.manager.BluetoothInteractionException;
import org.sputnikdev.bluetooth.manager.NotReadyException;

import java.util.Iterator;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.function.Function;
import java.util.function.Predicate;

class CompletableFutureService {

    private Logger logger = LoggerFactory.getLogger(CompletableFutureService.class);

    private final G governor;
    private final Predicate predicate;
    private final ConcurrentLinkedQueue> futures =
            new ConcurrentLinkedQueue<>();

    CompletableFutureService(G governor, Predicate predicate) {
        this.governor = governor;
        this.predicate = predicate;
    }

     CompletableFuture submit(Function function) {
        DeferredCompletableFuture future = new DeferredCompletableFuture<>(function);

        if (!predicate.test(governor)) {
            logger.debug("Governor is not ready, pushing the future to be completed when it is ready : {}",
                    governor.getURL());
            futures.add(future);
            return future;
        }

        logger.debug("Trying to complete future immediately: {}", governor.getURL());
        try {
            future.complete(function.apply(governor));
        } catch (BluetoothInteractionException | NotReadyException nativeException) {
            logger.warn("Bluetooth error happened while competing a future immediately: {} : {}",
                    governor.getURL(), nativeException.getMessage());
            futures.add(future);
        } catch (Exception ex) {
            logger.warn("Application error happened while competing a ready future: {} : {}",
                    governor.getURL(), ex.getMessage());
            future.completeExceptionally(ex);
        }

        return future;
    }

    void completeSilently() {
        try {
            complete();
        } catch (Exception ex) {
            logger.warn("Error occurred while completing (silently) futures: {}", ex.getMessage());
        }
    }

    @SuppressWarnings({"rawtypes", "unchecked"})
    void complete() throws BluetoothInteractionException, NotReadyException {
        logger.debug("Trying to complete futures: {} : {}", governor.getURL(), futures.size());

        if (!predicate.test(governor)) {
            logger.debug("Governor is not ready to complete the futures: {}: {}", governor.getURL(), futures.size());
            return;
        }

        for (Iterator> iterator = futures.iterator();
             iterator.hasNext(); ) {
            DeferredCompletableFuture next = iterator.next();
            if (next.isCancelled()) {
                iterator.remove();
                continue;
            }
            try {
                next.complete(next.getFunction().apply(governor));
            } catch (BluetoothInteractionException | NotReadyException nativeException) {
                logger.warn("Bluetooth error happened while competing a future: {} : {}",
                        governor.getURL(), nativeException.getMessage());
                // put affecting future to the end
                iterator.remove();
                futures.add(next);
                throw nativeException;
            } catch (Exception ex) {
                logger.warn("Application error happened while competing a future: {} : {}",
                        governor.getURL(), ex.getMessage());
                next.completeExceptionally(ex);
            }
            iterator.remove();
        }
    }

    void clear() {
        futures.forEach(future -> future.cancel(true));
        futures.clear();
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy