All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.taobao.drc.clusterclient.MessageNotifier Maven / Gradle / Ivy

There is a newer version: 5.0.0.1.beta
Show newest version
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);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy