package com.tesora.dve.groupmanager;
/*
* #%L
* Tesora Inc.
* Database Virtualization Engine
* %%
* Copyright (C) 2011 - 2014 Tesora Inc.
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
import com.tesora.dve.membership.GroupTopic;
import com.tesora.dve.membership.GroupTopicListener;
import io.netty.util.concurrent.DefaultThreadFactory;
import org.apache.log4j.Logger;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
public class LocalTopic<T> implements GroupTopic<T> {
static Logger log = Logger.getLogger(LocalTopic.class);
static Executor threadPool = Executors.newCachedThreadPool(new DefaultThreadFactory("localTopic"));
Map<GroupTopicListener<T>, AtomicInteger> listeners = new HashMap<GroupTopicListener<T>, AtomicInteger>();
@Override
public void addMessageListener(GroupTopicListener<T> listener) {
synchronized (listeners) {
if (false == listeners.containsKey(listener))
listeners.put(listener, new AtomicInteger());
listeners.get(listener).incrementAndGet();
}
}
@Override
public void removeMessageListener(GroupTopicListener<T> listener) {
synchronized (listeners) {
if (listeners.get(listener).decrementAndGet() == 0)
listeners.remove(listener);
}
}
@Override
public void publish(final T message) {
Set<GroupTopicListener<T>> messageReceivers;
synchronized (listeners) {
messageReceivers = new HashSet<GroupTopicListener<T>>(listeners.keySet());
}
final CountDownLatch latch = new CountDownLatch(messageReceivers.size());
for (final GroupTopicListener<T> l : messageReceivers)
threadPool.execute(new Runnable() {
@Override
public void run() {
l.onMessage(message);
latch.countDown();
}
});
try {
latch.await();
} catch (InterruptedException e) {
log.warn(e);
}
}
}