package org.apache.s4.comm; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import org.apache.s4.base.Emitter; import com.google.inject.Inject; import com.google.inject.name.Named; public class QueueingEmitter implements Emitter, Runnable { private Emitter emitter; private BlockingQueue<MessageHolder> queue; private long dropCount = 0; private volatile Thread thread; @Inject public QueueingEmitter(@Named("ll") Emitter emitter, @Named("comm.queue_emmiter_size") int queueSize) { this.emitter = emitter; queue = new LinkedBlockingQueue<MessageHolder>(queueSize); } public long getDropCount() { return dropCount; } public void start() { if (thread != null) { throw new IllegalStateException( "QueueingEmitter is already started"); } thread = new Thread(this, "QueueingEmitter"); thread.start(); } public void stop() { if (thread == null) { throw new IllegalStateException( "QueueingEmitter is already stopped"); } thread.interrupt(); thread = null; } @Override public boolean send(int partitionId, byte[] message) { MessageHolder mh = new MessageHolder(partitionId, message); if (!queue.offer(mh)) { dropCount++; return true; } else { return false; } } public void run() { while (!Thread.interrupted()) { try { MessageHolder mh = queue.take(); // System.out.println("QueueingEmitter: Sending message on low-level emitter"); emitter.send(mh.getPartitionId(), mh.getMessage()); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); } } } public int getPartitionCount() { return emitter.getPartitionCount(); } class MessageHolder { private int partitionId; private byte[] message; public int getPartitionId() { return partitionId; } public void setPartitionId(int partitionId) { this.partitionId = partitionId; } public byte[] getMessage() { return message; } public void setMessage(byte[] message) { this.message = message; } public MessageHolder(int partitionId, byte[] message) { super(); this.partitionId = partitionId; this.message = message; } } }