package org.yamcs.yarch; public class SpeedLimitStream extends AbstractStream implements StreamSubscriber { Stream input; volatile SpeedSpec speedSpec; private long ltst = -1; //time when the last tuple has been sent private long ltt = -1; //time of the last tuple sent /** * maximum time to wait if SPEED is ORIGINAL * meaning that if there is a gap in the data longer than this, we continue) */ public final static long MAX_WAIT_TIME=60000; public SpeedLimitStream(YarchDatabase dict, String name, TupleDefinition definition, SpeedSpec speedSpec){ super(dict, name, definition); this.speedSpec = speedSpec; } public void setSubscribedStream(Stream s) { this.input=s; } @Override public void start() { input.start(); } @Override public void onTuple(Stream s, Tuple t) { long waitTime=0; try { switch (speedSpec.getType()){ case AFAP: break; case FIXED_DELAY: long ctime=System.currentTimeMillis(); if(ltst!=-1) { waitTime=(long)(speedSpec.getFixedDelay()-(ctime-ltst)); } break; case ORIGINAL: long time=(Long)t.getColumn(speedSpec.column); if(ltt!=-1) { waitTime=(long) ((time-ltt)/speedSpec.getMultiplier()); } if(waitTime>MAX_WAIT_TIME) waitTime=MAX_WAIT_TIME; ltt=time; break; case STEP_BY_STEP: //TODO break; } if(waitTime>0) { Thread.sleep(waitTime); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); log.debug("Interrupt received ",e); } ltst=System.currentTimeMillis(); emitTuple(t); } /** * Called when the subcribed stream is closed * we close this stream also. */ @Override public void streamClosed(Stream stream) { close(); } public void setSpeedSpec(SpeedSpec speedSpec) { this.speedSpec=speedSpec; } @Override public String toString() { return "SPEED LIMIT "+speedSpec.toString(); } @Override protected void doClose() { input.close(); //TODO replace with removeSubscriber } public void changeSpeed(SpeedSpec speedSpec) { this.speedSpec = speedSpec; } }