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

io.castled.core.CastledBlockingQueue Maven / Gradle / Ivy

There is a newer version: 1.0.0
Show newest version
package io.castled.core;

import io.castled.exceptions.CastledRuntimeException;
import io.castled.utils.ThreadUtils;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;
import java.util.function.Consumer;

@Slf4j
public class CastledBlockingQueue {

    private final Consumer consumer;
    private final ExecutorService executorService;
    private final BlockingQueue blockingQueue;
    private volatile boolean shutDown = false;

    private boolean exitOnError = false;
    private volatile Exception failureException;

    public CastledBlockingQueue(Consumer childConsumer, int parallelism, int maxCapacity, boolean exitOnError) {
        this.consumer = decorateConsumer(childConsumer);
        this.executorService = Executors.newFixedThreadPool(parallelism);
        log.info("Parallelism {} , Max Capacity {}",parallelism,maxCapacity);
        this.blockingQueue = new ArrayBlockingQueue(maxCapacity);
        this.exitOnError = exitOnError;
        for (int i = 0; i < parallelism; i++) {
            executorService.execute(() -> {
                while (!shutDown) {
                    try {
                        T payload = blockingQueue.poll(1, TimeUnit.SECONDS);
                        if (payload != null) {
                            this.consumer.accept(payload);
                        }
                    } catch (Exception e) {
                        log.error("Blocking queue Consumer failed", e);
                        if (exitOnError) {
                            this.failureException = e;
                            break;
                        }
                    }
                }

            });

        }
    }

    public Consumer decorateConsumer(Consumer consumer) {
        return consumer;
    }

    public void writePayload(T payload, int timeout, TimeUnit timeUnit) throws TimeoutException {

        if (failureException != null) {
            shutdownNow();
            throw new CastledRuntimeException(failureException);
        }

        try {
            boolean success = blockingQueue.offer(payload, timeout, timeUnit);
            if (!success) {
                throw new TimeoutException();
            }
        } catch (InterruptedException e) {
            log.error("Blocking queue write payload interrupted", e);
            throw new CastledRuntimeException(e);
        }
    }

    public void flush(long timeOutMs) throws TimeoutException {

        while (!blockingQueue.isEmpty()) {
            if (exitOnError && failureException != null) {
                this.shutdownNow();
                throw new CastledRuntimeException(failureException);
            }
            ThreadUtils.interruptIgnoredSleep(500);
        }
        shutDown = true;
        executorService.shutdown();
        try {
            executorService.awaitTermination(60, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            executorService.shutdownNow();
        }
        if (exitOnError && failureException != null) {
            this.shutdownNow();
            throw new CastledRuntimeException(failureException);
        }
    }

    private void shutdownNow() {
        this.shutDown = true;
        this.executorService.shutdownNow();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy