/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.engine.cache; import org.fudgemsg.FudgeContext; import org.fudgemsg.FudgeMsg; import org.fudgemsg.mapping.FudgeDeserializer; import org.fudgemsg.mapping.FudgeSerializer; import com.opengamma.engine.cache.msg.CacheMessage; import com.opengamma.engine.cache.msg.SlaveChannelMessage; import com.opengamma.transport.FudgeConnection; import com.opengamma.transport.FudgeMessageReceiver; import com.opengamma.transport.FudgeSynchronousClient; import com.opengamma.util.ArgumentChecker; /** * {@link FudgeSynchronousClient} implementation for the remote cache component clients. The client * has a "get" and "put" channel. Although equal priority, this gives two blocking queues to isolate * operations that query the cache from those that update or control it. This allows, for example, * cache writes from a previous job to not delay loads needed by the next job. */ public class RemoteCacheClient { private class FudgeClient extends FudgeSynchronousClient { /** * @param requestSender */ protected FudgeClient(final FudgeConnection connection) { super(connection); } @Override protected Long getCorrelationIdFromReply(final FudgeMsg reply) { return reply.getLong(CacheMessage.CORRELATION_ID_KEY); } private <Request extends CacheMessage, Response extends CacheMessage> Response sendMessage(final Request request, final Class<Response> responseClass) { final FudgeSerializer scontext = new FudgeSerializer(getMessageSender().getFudgeContext()); final long correlationId = getNextCorrelationId(); request.setCorrelationId(correlationId); final FudgeMsg responseMsg = sendRequestAndWaitForResponse(FudgeSerializer.addClassHeader(scontext.objectToFudgeMsg(request), request.getClass(), CacheMessage.class), correlationId); final FudgeDeserializer dcontext = new FudgeDeserializer(getMessageSender().getFudgeContext()); final Response response = dcontext.fudgeMsgToObject(responseClass, responseMsg); return response; } private <Message extends CacheMessage> void postMessage(final Message message) { final FudgeSerializer scontext = new FudgeSerializer(getMessageSender().getFudgeContext()); sendMessage(FudgeSerializer.addClassHeader(scontext.objectToFudgeMsg(message), message.getClass(), CacheMessage.class)); } } private final FudgeClient _fudgeGets; private final FudgeClient _fudgePuts; /** * Creates a new client using a single underlying transport. * * @param connection the underlying transport */ public RemoteCacheClient(final FudgeConnection connection) { ArgumentChecker.notNull(connection, "connection"); _fudgeGets = new FudgeClient(connection); _fudgePuts = _fudgeGets; } /** * Creates a new client using a transport pair, one for cache "get" operations and one for "put" operations. * * @param requestGets get operations * @param requestPuts put operations */ public RemoteCacheClient(final FudgeConnection requestGets, final FudgeConnection requestPuts) { ArgumentChecker.notNull(requestGets, "requestGets"); ArgumentChecker.notNull(requestPuts, "requestPuts"); _fudgeGets = new FudgeClient(requestGets); if (requestPuts != requestGets) { _fudgeGets.postMessage(new SlaveChannelMessage()); _fudgePuts = new FudgeClient(requestPuts); } else { _fudgePuts = _fudgeGets; } } protected void setAsynchronousMessageReceiver(final FudgeMessageReceiver asynchronousMessageReceiver) { _fudgePuts.setAsynchronousMessageReceiver(asynchronousMessageReceiver); } protected <T extends CacheMessage> T sendGetMessage(final CacheMessage request, final Class<T> expectedResponse) { return _fudgeGets.sendMessage(request, expectedResponse); } protected <T extends CacheMessage> T sendPutMessage(final CacheMessage request, final Class<T> expectedResponse) { return _fudgePuts.sendMessage(request, expectedResponse); } protected FudgeContext getFudgeContext() { return _fudgeGets.getMessageSender().getFudgeContext(); } }