/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.bbg.replay;
import java.util.concurrent.BlockingQueue;
import org.fudgemsg.FudgeMsg;
import org.fudgemsg.mapping.FudgeDeserializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.opengamma.bbg.replay.BloombergTicksReplayer.Mode;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.TerminatableJob;
import com.opengamma.util.fudgemsg.OpenGammaFudgeContext;
/**
*
*/
public class TicksPlayerJob extends TerminatableJob {
/** Logger/ */
private static final Logger s_logger = LoggerFactory.getLogger(TicksPlayerJob.class);
private BlockingQueue<FudgeMsg> _ticksQueue;
private BloombergTickReceiver _tickReceiver;
private Mode _mode;
private Thread _ticksLoaderThread;
public TicksPlayerJob(BlockingQueue<FudgeMsg> ticksQueue, BloombergTickReceiver tickReceiver, Mode mode, Thread ticksLoaderThread) {
ArgumentChecker.notNull(ticksQueue, "ticksQueue");
ArgumentChecker.notNull(tickReceiver, "tickReceiver");
ArgumentChecker.notNull(mode, "mode");
ArgumentChecker.notNull(ticksLoaderThread, "ticksLoaderThread");
_ticksQueue = ticksQueue;
_tickReceiver = tickReceiver;
_mode = mode;
_ticksLoaderThread = ticksLoaderThread;
}
@Override
public void terminate() {
s_logger.debug("ticksPlayer terminating...");
super.terminate();
}
@Override
protected void runOneCycle() {
if (!_ticksLoaderThread.isAlive() && _ticksQueue.isEmpty()) {
terminate();
} else {
playNextTick();
}
}
/**
* @param nextTick
*
*/
private void playNextTick() {
FudgeDeserializer deserializer = new FudgeDeserializer(OpenGammaFudgeContext.getInstance());
switch (_mode) {
case ORIGINAL_LATENCY:
BloombergTick currentTick = null;;
try {
FudgeMsg msg = _ticksQueue.take();
if (msg != null && BloombergTickReplayUtils.isTerminateMsg(msg)) {
s_logger.debug("received terminate message");
terminate();
return;
}
currentTick = BloombergTick.fromFudgeMsg(deserializer, msg);
long ts1 = System.currentTimeMillis();
_tickReceiver.tickReceived(currentTick);
long ts2 = System.currentTimeMillis();
FudgeMsg nextMsg = _ticksQueue.peek();
if (nextMsg != null && !BloombergTickReplayUtils.isTerminateMsg(nextMsg)) {
BloombergTick nextTick = BloombergTick.fromFudgeMsg(deserializer, nextMsg);
long tickLatency = nextTick.getReceivedTS() - currentTick.getReceivedTS();
long sleepTime = tickLatency - (ts2 - ts1);
s_logger.debug("sleeping for {}ms,", sleepTime);
if (sleepTime > 0) {
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
Thread.interrupted();
s_logger.warn("interrupted from keeping time difference between ticks");
}
}
}
} catch (InterruptedException e1) {
Thread.interrupted();
s_logger.warn("interrupted while waiting to read ticks to play");
}
break;
case AS_FAST_AS_POSSIBLE:
BloombergTick tick = null;
try {
FudgeMsg msg = _ticksQueue.take();
if (msg != null && BloombergTickReplayUtils.isTerminateMsg(msg)) {
s_logger.debug("received terminate message");
terminate();
return;
}
tick = BloombergTick.fromFudgeMsg(deserializer, msg);
_tickReceiver.tickReceived(tick);
} catch (InterruptedException e) {
Thread.interrupted();
s_logger.warn("interrupted while waiting to read ticks to play");
}
break;
default:
break;
}
}
}