/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.livedata.server.distribution; import java.util.Collection; import java.util.Collections; import java.util.Set; import java.util.WeakHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import org.fudgemsg.FudgeContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.opengamma.util.fudgemsg.OpenGammaFudgeContext; import com.opengamma.util.jms.JmsConnector; /** * Factory to create JMS senders. */ public class JmsSenderFactory implements MarketDataSenderFactory { /** Logger. */ private static final Logger s_logger = LoggerFactory.getLogger(JmsSenderFactory.class); /** * A {@code WeakHashMap} is used here so the senders can be garbage collected * automatically when they're no longer used. */ private final Set<JmsSender> _allActiveSenders = Collections.newSetFromMap(new WeakHashMap<JmsSender, Boolean>()); /** * The JMS connector. */ private JmsConnector _jmsConnector; /** * The Fudge context. */ private FudgeContext _fudgeContext; /** * The executor. */ private final ExecutorService _executor; /** * Creates an instance. */ public JmsSenderFactory() { final int threads = Math.max(Runtime.getRuntime().availableProcessors(), 1) * 2; final ThreadPoolExecutor executor = new ThreadPoolExecutor(threads, threads, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>()); executor.allowCoreThreadTimeOut(true); _executor = executor; setFudgeContext(OpenGammaFudgeContext.getInstance()); } /** * Creates an instance. * * @param jmsConnector the JMS connector */ public JmsSenderFactory(JmsConnector jmsConnector) { this(); setJmsConnector(jmsConnector); } //------------------------------------------------------------------------- /** * Gets the JMS connector. * * @return the JMS connector */ public JmsConnector getJmsConnector() { return _jmsConnector; } /** * Sets the JMS connector. * * @param jmsConnector the connector */ public void setJmsConnector(JmsConnector jmsConnector) { _jmsConnector = jmsConnector; } /** * Gets the Fudge context. * * @return the Fudge context */ public FudgeContext getFudgeContext() { return _fudgeContext; } /** * Sets the Fudge context. * * @param fudgeContext the Fudge context */ public void setFudgeContext(FudgeContext fudgeContext) { _fudgeContext = fudgeContext; } //------------------------------------------------------------------------- public synchronized void transportInterrupted() { s_logger.warn("JMS transport interrupted; notifying {} senders", _allActiveSenders.size()); for (final JmsSender sender : _allActiveSenders) { _executor.execute(new Runnable() { @Override public void run() { sender.transportInterrupted(); } }); } } public synchronized void transportResumed() { s_logger.info("JMS transport resumed; notifying {} senders", _allActiveSenders.size()); for (final JmsSender sender : _allActiveSenders) { _executor.execute(new Runnable() { @Override public void run() { sender.transportResumed(); } }); } } @Override public synchronized Collection<MarketDataSender> create(MarketDataDistributor distributor) { s_logger.debug("Created JmsSender for {}", distributor); JmsSender sender = new JmsSender(_jmsConnector, distributor, getFudgeContext()); _allActiveSenders.add(sender); return Collections.<MarketDataSender>singleton(sender); } }