// Copyright © 2012-2020 VLINGO LABS. All rights reserved. // // This Source Code Form is subject to the terms of the // Mozilla Public License, v. 2.0. If a copy of the MPL // was not distributed with this file, You can obtain // one at https://mozilla.org/MPL/2.0/. package io.vlingo.actors.plugin.mailbox.concurrentqueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import io.vlingo.actors.Dispatcher; import io.vlingo.actors.Mailbox; public class ExecutorDispatcher implements Dispatcher { private final AtomicBoolean closed = new AtomicBoolean(false); private final ExecutorService executor; private final int numberOfThreads; protected ExecutorDispatcher(final int availableThreads, final int numberOfDispatchers, final float numberOfDispatchersFactor) { this.numberOfThreads = numberOfDispatchers > 0 ? numberOfDispatchers : (int) (availableThreads * numberOfDispatchersFactor); this.executor = new ThreadPoolExecutor(numberOfThreads, numberOfThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), new RejectionHandler()); } @Override public int concurrencyCapacity() { return numberOfThreads; } @Override public void close() { closed.set(true); executor.shutdown(); } @Override public boolean isClosed() { return closed.get(); } @Override public void execute(final Mailbox mailbox) { if (!closed.get()) { executor.execute(mailbox); } } @Override public boolean requiresExecutionNotification() { return false; } private class RejectionHandler implements RejectedExecutionHandler { @Override public void rejectedExecution(final Runnable runnable, final ThreadPoolExecutor executor) { if (!executor.isShutdown() && !executor.isTerminated()) throw new IllegalStateException("Message cannot be sent due to current system resource limitations."); } } }