package com.leansoft.luxun.producer.async; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.leansoft.luxun.api.generated.ProduceRequest; import com.leansoft.luxun.message.Message; import com.leansoft.luxun.message.MessageList; import com.leansoft.luxun.message.generated.CompressionCodec; import com.leansoft.luxun.producer.ProducerConfig; import com.leansoft.luxun.producer.SyncProducer; import com.leansoft.luxun.serializer.Encoder; public class DefaultEventHandler<T> implements EventHandler<T> { private final CallbackHandler<T> callbackHandler; private final Set<String> compressedTopics; private final CompressionCodec codec; private final Logger logger = LoggerFactory.getLogger(DefaultEventHandler.class); private final int numRetries; public DefaultEventHandler(ProducerConfig producerConfig, CallbackHandler<T> callbackHandler) { this.callbackHandler = callbackHandler; this.compressedTopics = new HashSet<String>(producerConfig.getCompressedTopics()); this.codec = producerConfig.getCompressionCodec(); this.numRetries = producerConfig.getNumRetries(); } @Override public void init(Properties properties) { } private void send(List<ProduceRequest> produceRequests, SyncProducer syncProducer) { if (produceRequests.isEmpty()) { return; } final int maxAttempts = 1 + numRetries; for(int i = 0; i < maxAttempts; i++) { try { syncProducer.multiSend(produceRequests); break; } catch (RuntimeException e) { logger.warn("error sending message, attempts times: " + i, e); if (i == maxAttempts - 1) { throw e; } } } } private List<ProduceRequest> collate(List<QueueItem<T>> events, Encoder<T> encoder) { final Map<String, MessageList> topicData = new HashMap<String, MessageList>(); for(QueueItem<T> event : events) { MessageList messageList = topicData.get(event.topic); if (messageList == null) { CompressionCodec useCodec = codec; if (codec != CompressionCodec.NO_COMPRESSION && !compressedTopics.isEmpty() && !compressedTopics.contains(event.topic)) { useCodec = CompressionCodec.NO_COMPRESSION; } messageList = new MessageList(useCodec); topicData.put(event.topic, messageList); } Message message = encoder.toMessage(event.data); messageList.add(message); } final List<ProduceRequest> requests = new ArrayList<ProduceRequest>(); for(String topic : topicData.keySet()) { MessageList messageList = topicData.get(topic); ProduceRequest produceRequest = new ProduceRequest(); produceRequest.setTopic(topic); ByteBuffer buffer = messageList.toThriftBuffer(); produceRequest.setItem(buffer); requests.add(produceRequest); } return requests; } @Override public void handle(List<QueueItem<T>> events, SyncProducer producer, Encoder<T> encoder) { List<QueueItem<T>> processedEvents = events; if (this.callbackHandler != null) { List<QueueItem<T>> items = this.callbackHandler.beforeSendingData(events); if (items != null) { processedEvents = items; } } List<ProduceRequest> collatedRequests = collate(processedEvents, encoder); send(collatedRequests, producer); } @Override public void close() { // TODO Auto-generated method stub } }