/** * Copyright (c) 2015 The original author or authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.reveno.atp.core.events; import org.reveno.atp.api.EventsManager; import org.reveno.atp.utils.MapUtils; import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.function.BiConsumer; import java.util.stream.Collectors; import java.util.stream.IntStream; @SuppressWarnings("unchecked") public class EventHandlersManager implements EventsManager { @Override public void asyncEventExecutors(int count) { close(); asyncListenersExecutor = IntStream.range(0, count) .mapToObj(i -> Executors.newSingleThreadExecutor()) .collect(Collectors.toList()); } public ExecutorService asyncEventExecutor() { // TODO when we call this method, we have sequencer, so we can apply // simple round-robin here, which will perform faster than random. return asyncListenersExecutor.get(rand.nextInt(asyncListenersExecutor.size())); } @Override public <E> void asyncEventHandler(Class<E> eventType, BiConsumer<E, EventMetadata> consumer) { asyncListeners.get(eventType).add((BiConsumer<Object, EventMetadata>) consumer); } @Override public <E> void eventHandler(Class<E> eventType, BiConsumer<E, EventMetadata> consumer) { listeners.get(eventType).add((BiConsumer<Object, EventMetadata>) consumer); } @Override public <E> void removeEventHandler(Class<E> eventType, BiConsumer<E, EventMetadata> consumer) { listeners.get(eventType).remove(consumer); } public Set<BiConsumer<Object, EventMetadata>> getEventHandlers(Class<?> eventType) { return listeners.get(eventType); } public Set<BiConsumer<Object, EventMetadata>> getAsyncHandlers(Class<?> eventType) { return asyncListeners.get(eventType); } public void close() { asyncListenersExecutor.forEach(ExecutorService::shutdown); } protected Random rand = new Random(); protected Map<Class<?>, Set<BiConsumer<Object, EventMetadata>>> listeners = MapUtils.repositorySet(); protected Map<Class<?>, Set<BiConsumer<Object, EventMetadata>>> asyncListeners = MapUtils.repositorySet(); protected List<ExecutorService> asyncListenersExecutor = Collections.singletonList(Executors.newSingleThreadExecutor()); }