package nl.tno.sensorstorm.impl;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import nl.tno.sensorstorm.api.particles.MetaParticle;
import nl.tno.sensorstorm.api.particles.Particle;
import nl.tno.sensorstorm.gracefullshutdown.GracefullShutdownParticle;
/**
* Special type of {@link SyncBuffer} which flushes itself after receiving a
* {@link GracefullShutdownParticle} from all it's sources.
* <p>
* This SyncBuffer learns who it's sources are. When it received a
* {@link GracefullShutdownParticle} from all it's sources, the pushParticle
* will behave like a flush.
*/
public class FlushingSyncBuffer extends SyncBuffer {
private final Map<String, Boolean> receivedShutdownFromOrigins = new HashMap<String, Boolean>();
/**
* Create a new {@link FlushingSyncBuffer} with a predefined buffer time. A
* value of 0 will effectively disable the buffer, and disable the filtering
* of duplicate {@link MetaParticle}s.
*
* @param bufferSizeMs
* Amount of time {@link Particle}s are kept in the buffer in
* milliseconds
*/
public FlushingSyncBuffer(long bufferSizeMs) {
super(bufferSizeMs);
}
@Override
public List<Particle> pushParticle(Particle particle) {
if (particle instanceof MetaParticle) {
if (!receivedShutdownFromOrigins
.containsKey(((MetaParticle) particle).getOriginId())) {
receivedShutdownFromOrigins.put(
((MetaParticle) particle).getOriginId(), false);
}
if (particle instanceof GracefullShutdownParticle) {
receivedShutdownFromOrigins.put(
((MetaParticle) particle).getOriginId(), true);
if (shouldFlush()) {
// Return everything in the buffer
// This MetaParticle is not relevant anymore
return flush();
}
}
}
return super.pushParticle(particle);
}
/**
* Check if this buffer has received a {@link GracefullShutdownParticle}
* form all known origins.
*
* @return Should the buffer flush?
*/
private boolean shouldFlush() {
for (Boolean b : receivedShutdownFromOrigins.values()) {
if (!b) {
return false;
}
}
return true;
}
@Override
public List<Particle> flush() {
receivedShutdownFromOrigins.clear();
return super.flush();
}
}