com.taobao.drc.clusterclient.MessageNotifier Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of consumer-core Show documentation
Show all versions of consumer-core Show documentation
The java consumer core component for Data Transmission Service
package com.taobao.drc.clusterclient;
import com.taobao.drc.clusterclient.partition.BaseCheckpoint;
import com.taobao.drc.clusterclient.partition.IPartition;
import com.taobao.drc.clusterclient.util.Gaugeable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
/**
* @author yangyang
* @since 2017/7/11
*/
public class MessageNotifier> implements Runnable, Gaugeable {
private static final String KEY_MESSAGE_PENDING_NUM = "queue.size";
private static final String KEY_MESSAGE_CAPACITY = "queue.capacity";
private static final String KEY_MESSAGE_SIZE = "notified.size";
private static final String KEY_MESSAGE_LAST_PERIOD_MS = "notified.sample_period_ms";
private static final String KEY_MESSAGE_RPS_LAST_PERIOD = "notified.rps";
private static final String KEY_MESSAGE_LAST_NOTIFIED_CHECKPOINT = "notified.last_notified_checkpoint";
private static final String KEY_MESSAGE_LATENCY = "notified.latency_sec";
private static final Logger logger = LoggerFactory.getLogger(MessageNotifier.class);
private final int queueSize;
private final BlockingQueue> msgQueue;
private final MessageListener messageListener;
private final Thread thread;
private volatile long consumedCounter = 0;
private volatile long lastSampleCounter = 0;
private volatile long lastSampleMs = System.currentTimeMillis();
private volatile M lastNotifiedMessage = null;
private volatile boolean running;
public MessageNotifier(MessageListener messageListener, int queueSize, String threadNamePrefix) {
this(messageListener, queueSize, threadNamePrefix, false);
}
public MessageNotifier(MessageListener messageListener, int queueSize, String threadNamePrefix, boolean fair) {
if (messageListener == null) {
throw new NullPointerException();
}
this.queueSize = queueSize;
this.messageListener = messageListener;
this.thread = new Thread(this);
this.thread.setName(threadNamePrefix + "notifier");
if (fair) {
this.msgQueue = new ArrayBlockingQueue>(queueSize, true);
} else {
this.msgQueue = new LinkedBlockingDeque>(queueSize);
}
this.running = true;
}
public void start() {
thread.start();
}
public void shutdown() throws InterruptedException {
running = false;
thread.interrupt();
thread.join();
}
@Override
public void run() {
while (running) {
try {
List messages = msgQueue.take();
try {
messageListener.notify(messages);
} finally {
consumedCounter += messages.size();
}
if (!messages.isEmpty()) {
lastNotifiedMessage = messages.get(messages.size() - 1);
}
} catch (InterruptedException e) {
logger.info("Notified was interrupted");
} catch (Exception e) {
logger.error("Caught exception in notifier", e);
messageListener.noException(e);
}
}
}
public void onMessages(List messages) throws InterruptedException {
if (messages == null) {
throw new NullPointerException();
}
this.msgQueue.put(messages);
}
@Override
public Map getMetrics() {
Map map = new TreeMap();
long now = System.currentTimeMillis();
long periodMs = (now - lastSampleMs);
long sampleCounter = consumedCounter;
long msgNum = sampleCounter - lastSampleCounter;
lastSampleMs = now;
lastSampleCounter = sampleCounter;
map.put(KEY_MESSAGE_SIZE, consumedCounter);
if (periodMs > 0) {
map.put(KEY_MESSAGE_LAST_PERIOD_MS, periodMs);
map.put(KEY_MESSAGE_RPS_LAST_PERIOD, msgNum * 1000 / periodMs);
}
map.put(KEY_MESSAGE_CAPACITY, queueSize);
map.put(KEY_MESSAGE_PENDING_NUM, msgQueue.size());
if (lastNotifiedMessage != null) {
map.put(KEY_MESSAGE_LAST_NOTIFIED_CHECKPOINT, lastNotifiedMessage.getCheckpoint());
if (lastNotifiedMessage.getCheckpoint() != null) {
long timestamp = Long.valueOf(lastNotifiedMessage.getCheckpoint().getTimestamp());
map.put(KEY_MESSAGE_LATENCY, System.currentTimeMillis() / 1000 - timestamp);
}
}
return map;
}
public void onExcepion(Exception e){
messageListener.noException(e);
}
}