package edu.harvard.mcb.leschziner.distributed;
import java.util.Vector;
import java.util.concurrent.BlockingQueue;
import com.hazelcast.core.ICollection;
import com.hazelcast.core.ItemEvent;
import com.hazelcast.core.ItemListener;
import edu.harvard.mcb.leschziner.core.Particle;
import edu.harvard.mcb.leschziner.core.ParticleConsumer;
import edu.harvard.mcb.leschziner.core.ParticleSource;
import edu.harvard.mcb.leschziner.storage.DefaultStorageEngine;
/**
* Base class for Particle consumers that consume off of distributed queues and
* distributes its processing of consumed particles
*
* @author spartango
*
*/
public abstract class DistributedParticleConsumer extends
DistributedTaskHandler implements
ParticleConsumer,
ItemListener<Particle> {
// Input Sources being watched
protected final Vector<ParticleSource> particleSources;
// Consumption Counter
protected int particlesConsumed;
/**
* Builds a particle consumer that is ready to attach sources
*/
public DistributedParticleConsumer() {
// Setup the distributed processing core
super();
particleSources = new Vector<ParticleSource>();
particlesConsumed = 0;
}
/**
* Add a source to be watched for new particles
*/
@Override public void addParticleSource(ParticleSource p) {
particleSources.add(p);
// Attach as listener
((ICollection<Particle>) p.getParticleQueue()).addItemListener(this,
true);
}
/**
* Process a newly received particle
*
* @param particle
* to be processed
*/
public abstract void processParticle(final Particle particle);
/**
* Get the queue from a queue modification event
*
* @param event
* @return queue event was generated by
*/
private static BlockingQueue<Particle>
queueFromEvent(ItemEvent<Particle> event) {
String sourceName = event.getSource().toString();
if (sourceName.startsWith("q:")) {
String queueName = sourceName.substring(2);
return DefaultStorageEngine.getStorageEngine().getQueue(queueName);
} else {
return null;
}
}
/**
* Handle item add events on particle source queues
*/
@Override public void itemAdded(ItemEvent<Particle> e) {
BlockingQueue<Particle> queue = queueFromEvent(e);
if (queue != null) {
// Queue Draining
Particle target = queue.poll();
if (target != null) {
particlesConsumed++;
processParticle(target);
}
}
}
@Override public void itemRemoved(ItemEvent<Particle> arg0) {
// Don't really care when items are removed
}
public int getParticlesConsumed() {
return particlesConsumed;
}
}