com.jn.agileway.dmmq.core.MessageTopic Maven / Gradle / Ivy
package com.jn.agileway.dmmq.core;
import com.jn.agileway.dmmq.core.allocator.DefaultTopicAllocator;
import com.jn.langx.lifecycle.*;
import com.jn.langx.util.Emptys;
import com.jn.langx.util.collection.Pipeline;
import com.jn.langx.util.function.Function;
import com.jn.langx.util.function.Functions;
import com.lmax.disruptor.TimeoutException;
import com.lmax.disruptor.dsl.Disruptor;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
public class MessageTopic extends AbstractLifecycle implements Destroyable {
private String name = DefaultTopicAllocator.TOPIC_DEFAULT;
private Disruptor> disruptor;
private MessageTopicConfiguration configuration;
private final MessageHolderFactory messageHolderFactory = new MessageHolderFactory();
private final ConcurrentHashMap> consumerMap = new ConcurrentHashMap>();
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public MessageTopicConfiguration getConfiguration() {
return configuration;
}
public void setConfiguration(MessageTopicConfiguration configuration) {
this.configuration = configuration;
}
public void subscribe(Consumer consumer, String... dependencies) {
if (Emptys.isNotEmpty(dependencies)) {
Consumer[] dependencyConsumers = (Consumer[]) Pipeline.of(dependencies).map(new Function>() {
@Override
public Consumer apply(String dependencyConsumerName) {
return consumerMap.get(dependencyConsumerName);
}
}).filter(Functions.>nonNullPredicate()).toArray();
disruptor.after(dependencyConsumers).then(consumer);
} else {
disruptor.handleEventsWith(consumer);
}
consumerMap.put(consumer.getName(), consumer);
}
@Override
public void doStart() {
disruptor.start();
}
@Override
public void doStop() {
try {
disruptor.shutdown(20L, TimeUnit.SECONDS);
} catch (TimeoutException ex) {
// ignore
}
}
@Override
public void destroy() {
shutdown();
}
@Override
public void doInit() {
if (configuration.getWaitStrategy() != null) {
disruptor = new Disruptor>(messageHolderFactory,
configuration.getRingBufferSize(),
configuration.getExecutor(),
configuration.getProducerType(),
configuration.getWaitStrategy());
} else {
disruptor = new Disruptor>(messageHolderFactory,
configuration.getRingBufferSize(),
configuration.getExecutor());
}
}
public void publish(M message) {
MessageTranslator translator = configuration.getMessageTranslator();
disruptor.publishEvent(translator, getName(), message);
}
}