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; } }